<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Phase 6: 通知范围权限中心 - 智能通知系统</title>
    
    <!-- 安全头配置 -->
    <meta http-equiv="Content-Security-Policy" content="
        default-src 'self'; 
        script-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net; 
        style-src 'self' 'unsafe-inline'; 
        img-src 'self' data: https:; 
        font-src 'self' https:; 
        connect-src 'self' http://localhost:48081 http://localhost:48082; 
        frame-src 'none'; 
        object-src 'none';
        base-uri 'self';
        form-action 'self';">
    <meta http-equiv="X-Content-Type-Options" content="nosniff">
    <meta http-equiv="X-Frame-Options" content="DENY">
    <meta http-equiv="X-XSS-Protection" content="1; mode=block">
    <meta http-equiv="Referrer-Policy" content="strict-origin-when-cross-origin">
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            min-height: 100vh;
            color: #333;
        }

        .container {
            max-width: 1600px;
            margin: 0 auto;
            padding: 20px;
        }

        .header {
            text-align: center;
            color: white;
            margin-bottom: 30px;
        }

        .header h1 {
            font-size: 2.5rem;
            margin-bottom: 10px;
            text-shadow: 2px 2px 4px rgba(0,0,0,0.3);
        }

        .header .subtitle {
            font-size: 1.2rem;
            opacity: 0.9;
            margin-bottom: 20px;
        }

        .feature-highlight {
            background: rgba(255, 193, 7, 0.15);
            border: 2px solid #ffc107;
            border-radius: 15px;
            padding: 20px;
            margin: 20px auto;
            max-width: 900px;
            backdrop-filter: blur(10px);
            box-shadow: 0 10px 30px rgba(255, 193, 7, 0.2);
        }

        .feature-highlight h3 {
            color: #ffc107;
            font-size: 1.3rem;
            margin-bottom: 15px;
            text-align: center;
            text-shadow: 1px 1px 2px rgba(0,0,0,0.5);
        }

        .feature-list {
            display: grid;
            grid-template-columns: 1fr 1fr;
            gap: 15px;
            color: white;
            font-size: 0.95rem;
        }

        .feature-item {
            background: rgba(255, 255, 255, 0.1);
            padding: 12px;
            border-radius: 8px;
            border-left: 4px solid #ffc107;
        }

        /* 阶段导航 */
        .phase-navigation {
            display: flex;
            justify-content: center;
            align-items: center;
            gap: 15px;
            margin-bottom: 40px;
            flex-wrap: wrap;
        }

        .phase-item {
            display: flex;
            align-items: center;
            gap: 8px;
            padding: 8px 16px;
            border-radius: 20px;
            font-weight: 500;
            transition: all 0.3s ease;
        }

        .phase-item.completed {
            background: rgba(76, 175, 80, 0.2);
            color: #4CAF50;
            border: 2px solid #4CAF50;
            cursor: pointer;
        }

        .phase-item.active {
            background: rgba(255, 193, 7, 0.2);
            color: #FFC107;
            border: 2px solid #FFC107;
            animation: pulse 2s infinite;
        }

        .phase-item.pending {
            background: rgba(255, 255, 255, 0.1);
            color: rgba(255, 255, 255, 0.6);
            border: 2px solid rgba(255, 255, 255, 0.3);
        }

        .phase-arrow {
            color: rgba(255, 255, 255, 0.5);
            font-size: 1.2rem;
        }

        @keyframes pulse {
            0% { box-shadow: 0 0 0 0 rgba(255, 193, 7, 0.7); }
            70% { box-shadow: 0 0 0 10px rgba(255, 193, 7, 0); }
            100% { box-shadow: 0 0 0 0 rgba(255, 193, 7, 0); }
        }

        /* 认证区域 */
        .auth-section {
            background: rgba(255, 255, 255, 0.95);
            backdrop-filter: blur(10px);
            border-radius: 20px;
            padding: 30px;
            margin-bottom: 30px;
            box-shadow: 0 20px 40px rgba(0,0,0,0.1);
            border: 1px solid rgba(255,255,255,0.2);
            transition: all 0.5s ease;
        }

        .auth-section.hidden {
            max-height: 80px;
            overflow: hidden;
            padding: 15px 30px;
        }

        .auth-toggle {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 20px;
        }

        .auth-form {
            display: grid;
            grid-template-columns: 1fr 1fr 1fr;
            gap: 20px;
            align-items: end;
        }

        .form-group {
            margin-bottom: 20px;
        }

        .form-group label {
            display: block;
            font-weight: 500;
            margin-bottom: 8px;
            color: #555;
        }

        .form-control {
            width: 100%;
            padding: 12px;
            border: 2px solid #e0e0e0;
            border-radius: 8px;
            font-size: 16px;
            transition: all 0.3s ease;
        }

        .form-control:focus {
            outline: none;
            border-color: #667eea;
            box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
        }

        .btn {
            padding: 12px 24px;
            border: none;
            border-radius: 8px;
            font-size: 16px;
            font-weight: 500;
            cursor: pointer;
            transition: all 0.3s ease;
            text-decoration: none;
            display: inline-flex;
            align-items: center;
            justify-content: center;
            gap: 8px;
        }

        .btn-primary {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            box-shadow: 0 4px 15px rgba(102, 126, 234, 0.3);
        }

        .btn-primary:hover {
            transform: translateY(-2px);
            box-shadow: 0 8px 25px rgba(102, 126, 234, 0.4);
        }

        .btn-secondary {
            background: #f8f9fa;
            color: #6c757d;
            border: 2px solid #e9ecef;
        }

        .btn-secondary:hover {
            background: #e9ecef;
            border-color: #dee2e6;
        }

        .btn-success {
            background: #28a745;
            color: white;
        }

        .btn-info {
            background: #17a2b8;
            color: white;
        }

        .btn-warning {
            background: #ffc107;
            color: #212529;
        }

        .btn:disabled {
            opacity: 0.6;
            cursor: not-allowed;
            transform: none !important;
        }

        /* 主内容区域 */
        .main-content {
            display: grid;
            grid-template-columns: 1fr 350px;
            gap: 30px;
            margin-bottom: 30px;
        }

        .content-card {
            background: rgba(255, 255, 255, 0.95);
            backdrop-filter: blur(10px);
            border-radius: 20px;
            padding: 30px;
            box-shadow: 0 20px 40px rgba(0,0,0,0.1);
            border: 1px solid rgba(255,255,255,0.2);
        }

        .card-title {
            font-size: 1.5rem;
            font-weight: 600;
            margin-bottom: 20px;
            color: #333;
            display: flex;
            align-items: center;
            gap: 10px;
        }

        /* 权限矩阵表格 */
        .permission-matrix {
            overflow-x: auto;
        }

        .matrix-table {
            width: 100%;
            border-collapse: collapse;
            background: white;
            border-radius: 12px;
            overflow: hidden;
            box-shadow: 0 4px 15px rgba(0,0,0,0.1);
        }

        .matrix-table th,
        .matrix-table td {
            padding: 15px 12px;
            text-align: center;
            border: 1px solid #e9ecef;
            transition: all 0.3s ease;
        }

        .matrix-table th {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            font-weight: 600;
            text-shadow: 1px 1px 2px rgba(0,0,0,0.3);
        }

        .matrix-table td {
            position: relative;
            cursor: pointer;
        }

        .matrix-table td:hover {
            background: #f8f9fa;
            transform: scale(1.05);
        }

        .permission-cell {
            display: flex;
            align-items: center;
            justify-content: center;
            min-height: 40px;
        }

        .permission-allowed {
            background: linear-gradient(135deg, #d4edda 0%, #c3e6cb 100%);
            color: #155724;
            font-weight: 600;
        }

        .permission-denied {
            background: linear-gradient(135deg, #f8d7da 0%, #f5c6cb 100%);
            color: #721c24;
        }

        .permission-conditional {
            background: linear-gradient(135deg, #fff3cd 0%, #ffeaa7 100%);
            color: #856404;
            font-weight: 500;
        }

        /* 范围选择器 - 增强版本 */
        .scope-selector {
            margin-bottom: 30px;
        }

        .scope-selector-controls {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 20px;
            flex-wrap: wrap;
            gap: 10px;
        }

        .scope-mode-toggle {
            display: flex;
            background: #f8f9fa;
            border-radius: 25px;
            padding: 4px;
            border: 2px solid #e9ecef;
        }

        .scope-mode-btn {
            padding: 8px 16px;
            border: none;
            background: transparent;
            border-radius: 20px;
            cursor: pointer;
            font-size: 0.9rem;
            transition: all 0.3s ease;
            font-weight: 500;
        }

        .scope-mode-btn.active {
            background: #667eea;
            color: white;
            box-shadow: 0 2px 8px rgba(102, 126, 234, 0.3);
        }

        .scope-options {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
            gap: 20px;
            margin-bottom: 25px;
        }

        .scope-option {
            background: white;
            border: 2px solid #e9ecef;
            border-radius: 15px;
            padding: 25px 20px;
            cursor: pointer;
            transition: all 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94);
            text-align: center;
            position: relative;
            overflow: hidden;
        }

        .scope-option::before {
            content: '';
            position: absolute;
            top: 0;
            left: -100%;
            width: 100%;
            height: 100%;
            background: linear-gradient(90deg, transparent, rgba(255,255,255,0.2), transparent);
            transition: left 0.5s ease;
        }

        .scope-option:hover::before {
            left: 100%;
        }

        .scope-option:hover {
            border-color: #667eea;
            transform: translateY(-5px) scale(1.02);
            box-shadow: 0 12px 35px rgba(102, 126, 234, 0.25);
        }

        .scope-option.selected {
            border-color: #28a745;
            background: linear-gradient(135deg, #d4edda 0%, #c3e6cb 100%);
            color: #155724;
            transform: translateY(-3px) scale(1.02);
            box-shadow: 0 8px 30px rgba(40, 167, 69, 0.3);
        }

        .scope-option.selected .scope-icon {
            animation: bounce 0.6s ease-out;
        }

        .scope-option.disabled {
            opacity: 0.4;
            cursor: not-allowed;
            background: #f8f9fa;
            transform: none !important;
            box-shadow: none !important;
        }

        .scope-option.disabled:hover {
            border-color: #e9ecef;
            box-shadow: none;
        }

        .scope-icon {
            font-size: 2.5rem;
            margin-bottom: 12px;
            transition: all 0.3s ease;
        }

        .scope-title {
            font-weight: 600;
            margin-bottom: 10px;
            font-size: 1.1rem;
        }

        .scope-description {
            font-size: 0.9rem;
            opacity: 0.8;
            line-height: 1.4;
            margin-bottom: 12px;
        }

        .scope-permission-badge {
            display: inline-flex;
            align-items: center;
            gap: 6px;
            padding: 6px 12px;
            border-radius: 15px;
            font-size: 0.8rem;
            font-weight: 600;
            margin-top: 10px;
        }

        .scope-permission-badge.available {
            background: rgba(40, 167, 69, 0.1);
            color: #28a745;
            border: 1px solid rgba(40, 167, 69, 0.3);
        }

        .scope-permission-badge.unavailable {
            background: rgba(220, 53, 69, 0.1);
            color: #dc3545;
            border: 1px solid rgba(220, 53, 69, 0.3);
        }

        .scope-permission-level {
            font-size: 0.75rem;
            opacity: 0.9;
            margin-top: 5px;
        }

        .scope-selection-summary {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            padding: 20px;
            border-radius: 15px;
            margin: 20px 0;
            text-align: center;
        }

        .scope-selection-count {
            font-size: 2rem;
            font-weight: 700;
            margin-bottom: 8px;
        }

        .scope-selection-label {
            font-size: 0.9rem;
            opacity: 0.9;
        }

        @keyframes bounce {
            0%, 20%, 50%, 80%, 100% {
                transform: translateY(0);
            }
            40% {
                transform: translateY(-10px);
            }
            60% {
                transform: translateY(-5px);
            }
        }

        @keyframes pulse-glow {
            0% {
                box-shadow: 0 0 0 0 rgba(40, 167, 69, 0.7);
            }
            70% {
                box-shadow: 0 0 0 10px rgba(40, 167, 69, 0);
            }
            100% {
                box-shadow: 0 0 0 0 rgba(40, 167, 69, 0);
            }
        }

        .scope-option.selected {
            animation: pulse-glow 2s infinite;
        }

        /* 测试结果展示 */
        .test-results {
            margin-top: 20px;
            padding: 20px;
            background: #f8f9fa;
            border-radius: 12px;
            border-left: 4px solid #17a2b8;
        }

        .test-result-item {
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 10px 0;
            border-bottom: 1px solid #e9ecef;
        }

        .test-result-item:last-child {
            border-bottom: none;
        }

        .result-success {
            color: #28a745;
        }

        .result-error {
            color: #dc3545;
        }

        .result-warning {
            color: #ffc107;
        }

        /* 用户信息面板 */
        .user-info {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            border-radius: 15px;
            padding: 20px;
            margin-bottom: 20px;
        }

        .user-avatar {
            width: 60px;
            height: 60px;
            border-radius: 50%;
            background: rgba(255,255,255,0.2);
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 1.5rem;
            margin: 0 auto 15px;
        }

        .user-details {
            text-align: center;
        }

        .user-name {
            font-size: 1.2rem;
            font-weight: 600;
            margin-bottom: 5px;
        }

        .user-role {
            opacity: 0.8;
            font-size: 0.9rem;
        }

        /* 权限说明 */
        .permission-info {
            background: #f8f9fa;
            border-radius: 12px;
            padding: 20px;
            margin-bottom: 20px;
        }

        .permission-title {
            font-weight: 600;
            margin-bottom: 15px;
            color: #333;
        }

        .permission-list {
            list-style: none;
        }

        .permission-list li {
            padding: 8px 0;
            border-bottom: 1px solid #e9ecef;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }

        .permission-list li:last-child {
            border-bottom: none;
        }

        .permission-check {
            color: #27ae60;
            font-size: 1.1rem;
        }

        .permission-cross {
            color: #e74c3c;
            font-size: 1.1rem;
        }

        /* 测试日志 */
        .log-container {
            max-height: 300px;
            overflow-y: auto;
            background: #f8f9fa;
            padding: 20px;
            border-radius: 12px;
            font-family: monospace;
            font-size: 14px;
        }

        /* 权限边界测试系统样式 */
        .permission-boundary-testing {
            margin: 30px 0;
            padding: 25px;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            border-radius: 20px;
            color: white;
            box-shadow: 0 15px 35px rgba(102, 126, 234, 0.3);
        }

        .testing-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 25px;
        }

        .testing-title {
            font-size: 1.4rem;
            font-weight: 700;
            display: flex;
            align-items: center;
            gap: 10px;
        }

        .test-mode-selector {
            display: flex;
            background: rgba(255, 255, 255, 0.1);
            border-radius: 25px;
            padding: 4px;
        }

        .test-mode-btn {
            padding: 8px 16px;
            border: none;
            background: transparent;
            color: white;
            border-radius: 20px;
            cursor: pointer;
            font-size: 0.9rem;
            transition: all 0.3s ease;
            font-weight: 500;
        }

        .test-mode-btn.active {
            background: rgba(255, 255, 255, 0.2);
            box-shadow: 0 2px 8px rgba(255, 255, 255, 0.3);
        }

        .test-scenario-grid {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
            gap: 15px;
            margin-bottom: 25px;
        }

        .test-scenario-card {
            background: rgba(255, 255, 255, 0.1);
            border-radius: 15px;
            padding: 20px;
            cursor: pointer;
            transition: all 0.3s ease;
            border: 2px solid transparent;
            position: relative;
        }

        .test-scenario-card:hover {
            background: rgba(255, 255, 255, 0.15);
            transform: translateY(-2px);
            box-shadow: 0 8px 25px rgba(255, 255, 255, 0.2);
        }

        .test-scenario-card.selected {
            border-color: rgba(255, 255, 255, 0.5);
            background: rgba(255, 255, 255, 0.2);
        }

        .test-scenario-header {
            display: flex;
            align-items: center;
            gap: 10px;
            margin-bottom: 12px;
        }

        .test-scenario-icon {
            font-size: 1.5rem;
        }

        .test-scenario-title {
            font-weight: 600;
            font-size: 1.1rem;
        }

        .test-scenario-desc {
            font-size: 0.9rem;
            opacity: 0.9;
            line-height: 1.4;
            margin-bottom: 15px;
        }

        .test-scenario-stats {
            display: grid;
            grid-template-columns: 1fr 1fr;
            gap: 10px;
            font-size: 0.8rem;
        }

        .test-stat {
            background: rgba(255, 255, 255, 0.1);
            padding: 6px 10px;
            border-radius: 8px;
            text-align: center;
        }

        .batch-test-controls {
            display: flex;
            justify-content: space-between;
            align-items: center;
            flex-wrap: wrap;
            gap: 10px;
        }

        .test-progress-container {
            margin: 20px 0;
            padding: 20px;
            background: rgba(255, 255, 255, 0.95);
            border-radius: 15px;
            display: none;
        }

        .test-progress-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 15px;
            color: #333;
        }

        .test-progress-bar {
            background: #e9ecef;
            border-radius: 10px;
            height: 20px;
            overflow: hidden;
            margin-bottom: 15px;
        }

        .test-progress-fill {
            background: linear-gradient(90deg, #28a745, #20c997);
            height: 100%;
            transition: width 0.3s ease;
            display: flex;
            align-items: center;
            justify-content: center;
            color: white;
            font-size: 0.8rem;
            font-weight: 600;
        }

        .test-progress-stats {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
            gap: 15px;
        }

        .progress-stat {
            text-align: center;
            padding: 10px;
            background: #f8f9fa;
            border-radius: 8px;
            border-left: 4px solid #667eea;
        }

        .progress-stat-value {
            font-size: 1.2rem;
            font-weight: 600;
            color: #333;
        }

        .progress-stat-label {
            font-size: 0.8rem;
            color: #666;
            margin-top: 4px;
        }

        .realtime-results {
            margin: 20px 0;
            max-height: 400px;
            overflow-y: auto;
            background: white;
            border-radius: 15px;
            border: 2px solid #e9ecef;
        }

        .result-item {
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 12px 20px;
            border-bottom: 1px solid #e9ecef;
            transition: all 0.3s ease;
        }

        .result-item:hover {
            background: #f8f9fa;
        }

        .result-item:last-child {
            border-bottom: none;
        }

        .result-left {
            display: flex;
            align-items: center;
            gap: 12px;
        }

        .result-icon {
            width: 32px;
            height: 32px;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 0.9rem;
            font-weight: 600;
        }

        .result-icon.success {
            background: #d4edda;
            color: #155724;
        }

        .result-icon.failure {
            background: #f8d7da;
            color: #721c24;
        }

        .result-icon.pending {
            background: #fff3cd;
            color: #856404;
        }

        .result-info {
            flex: 1;
        }

        .result-title {
            font-weight: 600;
            color: #333;
            margin-bottom: 2px;
        }

        .result-desc {
            font-size: 0.8rem;
            color: #666;
        }

        .result-right {
            display: flex;
            align-items: center;
            gap: 8px;
            font-size: 0.8rem;
            color: #666;
        }

        .result-time {
            opacity: 0.8;
        }

        .result-status {
            padding: 4px 8px;
            border-radius: 12px;
            font-weight: 600;
            font-size: 0.75rem;
        }

        .result-status.success {
            background: #d4edda;
            color: #155724;
        }

        .result-status.failure {
            background: #f8d7da;
            color: #721c24;
        }

        .result-status.pending {
            background: #fff3cd;
            color: #856404;
        }

        .test-report {
            margin-top: 25px;
            padding: 20px;
            background: rgba(255, 255, 255, 0.95);
            border-radius: 15px;
            color: #333;
            display: none;
        }

        .report-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 20px;
            padding-bottom: 15px;
            border-bottom: 2px solid #e9ecef;
        }

        .report-title {
            font-size: 1.3rem;
            font-weight: 700;
            color: #333;
        }

        .report-export {
            display: flex;
            gap: 10px;
        }

        .export-btn {
            padding: 6px 12px;
            border: 1px solid #dee2e6;
            background: #f8f9fa;
            border-radius: 6px;
            font-size: 0.8rem;
            cursor: pointer;
            transition: all 0.3s ease;
        }

        .export-btn:hover {
            background: #e9ecef;
        }

        .report-summary {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
            gap: 15px;
            margin-bottom: 25px;
        }

        .summary-card {
            background: #f8f9fa;
            border-radius: 12px;
            padding: 15px;
            text-align: center;
            border-left: 4px solid #667eea;
        }

        .summary-value {
            font-size: 1.5rem;
            font-weight: 700;
            color: #333;
            margin-bottom: 5px;
        }

        .summary-label {
            font-size: 0.8rem;
            color: #666;
        }

        .report-details {
            background: #f8f9fa;
            border-radius: 12px;
            padding: 20px;
        }

        .report-section {
            margin-bottom: 20px;
        }

        .report-section:last-child {
            margin-bottom: 0;
        }

        .section-title {
            font-size: 1.1rem;
            font-weight: 600;
            color: #333;
            margin-bottom: 10px;
            display: flex;
            align-items: center;
            gap: 8px;
        }

        .comparison-matrix {
            overflow-x: auto;
        }

        .comparison-table {
            width: 100%;
            border-collapse: collapse;
            background: white;
            border-radius: 8px;
            overflow: hidden;
            box-shadow: 0 2px 8px rgba(0,0,0,0.1);
        }

        .comparison-table th,
        .comparison-table td {
            padding: 10px 12px;
            text-align: center;
            border-bottom: 1px solid #e9ecef;
        }

        .comparison-table th {
            background: #f8f9fa;
            font-weight: 600;
            color: #495057;
        }

        .comparison-result {
            display: flex;
            align-items: center;
            justify-content: center;
            gap: 6px;
        }

        .comparison-result.match {
            color: #28a745;
        }

        .comparison-result.mismatch {
            color: #dc3545;
        }

        /* 导航按钮 */
        .navigation-section {
            text-align: center;
            margin-top: 40px;
        }

        .btn-nav {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            padding: 15px 30px;
            font-size: 1.1rem;
            border-radius: 50px;
            text-decoration: none;
            display: inline-flex;
            align-items: center;
            gap: 10px;
            box-shadow: 0 8px 25px rgba(102, 126, 234, 0.3);
            transition: all 0.3s ease;
            margin: 0 10px;
        }

        .btn-nav:hover {
            transform: translateY(-3px);
            box-shadow: 0 12px 35px rgba(102, 126, 234, 0.4);
        }

        /* 加载状态 */
        .loading {
            display: flex;
            align-items: center;
            justify-content: center;
            padding: 40px;
            font-size: 1.1rem;
            color: #666;
        }

        .spinner {
            width: 20px;
            height: 20px;
            border: 2px solid #f0f0f0;
            border-top: 2px solid #667eea;
            border-radius: 50%;
            animation: spin 1s linear infinite;
            margin-right: 10px;
        }

        @keyframes spin {
            0% { transform: rotate(0deg); }
            100% { transform: rotate(360deg); }
        }

        /* 错误和成功消息 */
        .alert {
            padding: 15px;
            border-radius: 8px;
            margin-bottom: 20px;
            font-weight: 500;
        }

        .alert-success {
            background: #d4edda;
            color: #155724;
            border: 1px solid #c3e6cb;
        }

        .alert-error {
            background: #f8d7da;
            color: #721c24;
            border: 1px solid #f5c6cb;
        }

        .alert-warning {
            background: #fff3cd;
            color: #856404;
            border: 1px solid #ffeaa7;
        }

        .alert-info {
            background: #d1ecf1;
            color: #0c5460;
            border: 1px solid #bee5eb;
        }

        /* ==================== 响应式设计系统 ==================== */
        
        /* 基础响应式变量 */
        :root {
            --mobile-padding: 12px;
            --tablet-padding: 20px;
            --desktop-padding: 30px;
            --large-padding: 40px;
            
            --mobile-font-base: 14px;
            --tablet-font-base: 15px;
            --desktop-font-base: 16px;
            
            --mobile-border-radius: 8px;
            --tablet-border-radius: 12px;
            --desktop-border-radius: 16px;
            --large-border-radius: 20px;
        }

        /* ========== 超小屏设备 (320px - 480px) ========== */
        @media (max-width: 480px) {
            .container {
                padding: var(--mobile-padding);
                max-width: 100%;
            }

            .header h1 {
                font-size: 1.8rem;
                margin-bottom: 8px;
                text-align: center;
            }

            .header .subtitle {
                font-size: 1rem;
                margin-bottom: 15px;
            }

            /* 特性高亮区域 */
            .feature-highlight {
                padding: 15px;
                margin: 15px 0;
                border-radius: var(--mobile-border-radius);
            }

            .feature-list {
                grid-template-columns: 1fr;
                gap: 10px;
            }

            .feature-item {
                padding: 10px;
                font-size: 0.85rem;
            }

            /* 阶段导航 */
            .phase-navigation {
                flex-direction: column;
                gap: 8px;
                margin-bottom: 25px;
            }

            .phase-item {
                padding: 8px 16px;
                font-size: 0.85rem;
                width: 100%;
                justify-content: center;
            }

            .phase-arrow {
                display: none;
            }

            /* 认证表单 */
            .auth-form {
                grid-template-columns: 1fr;
                gap: 15px;
            }

            .form-control {
                padding: 14px 12px; /* 增加触摸目标 */
                font-size: var(--mobile-font-base);
                border-radius: var(--mobile-border-radius);
            }

            .btn {
                padding: 14px 20px; /* 增加触摸目标 */
                font-size: var(--mobile-font-base);
                min-height: 44px; /* 符合移动端最小触摸目标 */
                border-radius: var(--mobile-border-radius);
            }

            /* 主内容区域 */
            .main-content {
                grid-template-columns: 1fr;
                gap: 20px;
            }

            .content-card {
                padding: 20px;
                border-radius: var(--mobile-border-radius);
            }

            .card-title {
                font-size: 1.3rem;
                margin-bottom: 15px;
            }

            /* 权限矩阵表格 */
            .matrix-table {
                font-size: 0.8rem;
                border-radius: var(--mobile-border-radius);
            }

            .matrix-table th,
            .matrix-table td {
                padding: 8px 4px;
                min-width: 60px;
            }

            .matrix-table th {
                font-size: 0.75rem;
            }

            /* 范围选择器 */
            .scope-options {
                grid-template-columns: 1fr;
                gap: 15px;
            }

            .scope-option {
                padding: 20px 15px;
                border-radius: var(--mobile-border-radius);
                min-height: 120px; /* 确保足够的触摸区域 */
            }

            .scope-icon {
                font-size: 2rem;
                margin-bottom: 8px;
            }

            .scope-title {
                font-size: 1rem;
            }

            .scope-description {
                font-size: 0.85rem;
            }

            /* 用户信息面板 */
            .user-avatar {
                width: 50px;
                height: 50px;
            }

            .user-name {
                font-size: 1.1rem;
            }

            .user-role {
                font-size: 0.85rem;
            }
        }

        /* ========== 小屏设备 (481px - 768px) ========== */
        @media (min-width: 481px) and (max-width: 768px) {
            .container {
                padding: var(--tablet-padding);
            }

            .header h1 {
                font-size: 2.2rem;
            }

            .header .subtitle {
                font-size: 1.1rem;
            }

            /* 阶段导航 */
            .phase-navigation {
                gap: 12px;
                justify-content: center;
            }

            .phase-item {
                padding: 8px 14px;
                font-size: 0.9rem;
            }

            /* 认证表单 */
            .auth-form {
                grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
                gap: 18px;
            }

            /* 主内容区域 */
            .main-content {
                grid-template-columns: 1fr;
                gap: 25px;
            }

            .content-card {
                padding: 25px;
                border-radius: var(--tablet-border-radius);
            }

            /* 范围选择器 */
            .scope-options {
                grid-template-columns: repeat(2, 1fr);
                gap: 18px;
            }

            .scope-option {
                padding: 22px 18px;
                border-radius: var(--tablet-border-radius);
            }

            /* 权限矩阵表格 */
            .matrix-table th,
            .matrix-table td {
                padding: 10px 8px;
                font-size: 0.9rem;
            }
        }

        /* ========== 平板设备 (769px - 1024px) ========== */
        @media (min-width: 769px) and (max-width: 1024px) {
            .container {
                padding: var(--tablet-padding);
                max-width: 95%;
            }

            /* 主内容区域 */
            .main-content {
                grid-template-columns: 2fr 1fr;
                gap: 25px;
            }

            /* 认证表单 */
            .auth-form {
                grid-template-columns: repeat(2, 1fr) auto;
                gap: 20px;
            }

            /* 范围选择器 */
            .scope-options {
                grid-template-columns: repeat(3, 1fr);
                gap: 20px;
            }

            .scope-option {
                padding: 24px 20px;
                border-radius: var(--tablet-border-radius);
            }

            /* 权限矩阵表格 */
            .matrix-table th,
            .matrix-table td {
                padding: 12px 10px;
            }
        }

        /* ========== 桌面设备 (1025px - 1440px) ========== */
        @media (min-width: 1025px) and (max-width: 1440px) {
            .container {
                padding: var(--desktop-padding);
                max-width: 1400px;
            }

            /* 主内容区域 */
            .main-content {
                grid-template-columns: 1fr 380px;
                gap: 30px;
            }

            /* 认证表单 */
            .auth-form {
                grid-template-columns: 1fr 1fr 1fr;
                gap: 20px;
            }

            /* 范围选择器 */
            .scope-options {
                grid-template-columns: repeat(4, 1fr);
                gap: 20px;
            }

            .scope-option {
                padding: 25px 20px;
                border-radius: var(--desktop-border-radius);
            }

            /* 内容卡片 */
            .content-card {
                padding: var(--desktop-padding);
                border-radius: var(--desktop-border-radius);
            }
        }

        /* ========== 大屏设备 (1441px+) ========== */
        @media (min-width: 1441px) {
            .container {
                padding: var(--large-padding);
                max-width: 1600px;
            }

            .header h1 {
                font-size: 2.8rem;
            }

            .header .subtitle {
                font-size: 1.3rem;
            }

            /* 主内容区域 */
            .main-content {
                grid-template-columns: 1fr 400px;
                gap: 40px;
            }

            /* 范围选择器 */
            .scope-options {
                grid-template-columns: repeat(4, 1fr);
                gap: 25px;
            }

            .scope-option {
                padding: 30px 25px;
                border-radius: var(--large-border-radius);
            }

            /* 内容卡片 */
            .content-card {
                padding: var(--large-padding);
                border-radius: var(--large-border-radius);
            }

            /* 权限矩阵表格 */
            .matrix-table th,
            .matrix-table td {
                padding: 15px 12px;
            }
        }

        /* ========== 响应式图表优化 ========== */
        @media (max-width: 768px) {
            .chart-container {
                overflow-x: auto;
                -webkit-overflow-scrolling: touch;
            }
            
            .chart-container canvas {
                min-width: 300px !important;
            }
        }

        /* ========== 打印样式 ========== */
        @media print {
            .no-print,
            .auth-section,
            .phase-navigation,
            .scope-selector {
                display: none !important;
            }
            
            .container {
                max-width: none;
                padding: 0;
            }
            
            .content-card {
                box-shadow: none;
                border: 1px solid #000;
            }
        }

        /* 隐藏类 */
        .d-none {
            display: none !important;
        }

        .d-block {
            display: block !important;
        }

        /* 动画效果 */
        @keyframes fadeInUp {
            from {
                opacity: 0;
                transform: translateY(30px);
            }
            to {
                opacity: 1;
                transform: translateY(0);
            }
        }

        .fade-in-up {
            animation: fadeInUp 0.6s ease-out;
        }

        /* 权限级别颜色 */
        .level-1 { background: linear-gradient(135deg, #ff6b6b 0%, #ee5a24 100%); }
        .level-2 { background: linear-gradient(135deg, #feca57 0%, #ff9f43 100%); }
        .level-3 { background: linear-gradient(135deg, #48dbfb 0%, #0abde3 100%); }
        .level-4 { background: linear-gradient(135deg, #1dd1a1 0%, #10ac84 100%); }

        /* 权限矩阵增强可视化样式 */
        .matrix-visualization-container {
            display: grid;
            grid-template-columns: 1fr 1fr;
            gap: 30px;
            margin: 30px 0;
        }

        .chart-container {
            background: white;
            border-radius: 15px;
            padding: 20px;
            box-shadow: 0 8px 25px rgba(0,0,0,0.1);
            position: relative;
        }

        .chart-title {
            font-size: 1.2rem;
            font-weight: 600;
            margin-bottom: 15px;
            color: #333;
            text-align: center;
        }

        .heatmap-container {
            display: grid;
            grid-template-columns: auto repeat(4, 1fr);
            gap: 2px;
            margin: 20px 0;
            font-size: 0.9rem;
        }

        .heatmap-cell {
            padding: 12px 8px;
            text-align: center;
            border-radius: 4px;
            transition: all 0.3s ease;
            cursor: pointer;
            min-height: 40px;
            display: flex;
            align-items: center;
            justify-content: center;
        }

        .heatmap-header {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            font-weight: 600;
        }

        .heatmap-role-header {
            background: #f8f9fa;
            color: #333;
            font-weight: 600;
        }

        .heatmap-level-0 { background: #f8f9fa; color: #6c757d; }
        .heatmap-level-1 { background: #ffebee; color: #c62828; }
        .heatmap-level-2 { background: #fff3e0; color: #ef6c00; }
        .heatmap-level-3 { background: #e3f2fd; color: #1565c0; }
        .heatmap-level-4 { background: #e8f5e8; color: #2e7d32; }

        .permission-detail-modal {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0, 0, 0, 0.7);
            display: flex;
            align-items: center;
            justify-content: center;
            z-index: 10000;
            opacity: 0;
            visibility: hidden;
            transition: all 0.3s ease;
        }

        .permission-detail-modal.show {
            opacity: 1;
            visibility: visible;
        }

        .permission-detail-content {
            background: white;
            border-radius: 20px;
            padding: 30px;
            max-width: 600px;
            max-height: 80vh;
            overflow-y: auto;
            box-shadow: 0 20px 60px rgba(0,0,0,0.3);
            transform: translateY(20px);
            transition: transform 0.3s ease;
        }

        .permission-detail-modal.show .permission-detail-content {
            transform: translateY(0);
        }

        .level-detail-item {
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 12px;
            margin: 8px 0;
            border-radius: 8px;
            transition: all 0.3s ease;
        }

        .level-detail-item:hover {
            transform: translateX(5px);
        }

        .level-detail-allowed {
            background: linear-gradient(135deg, #d4edda 0%, #c3e6cb 100%);
            border-left: 4px solid #28a745;
        }

        .level-detail-denied {
            background: linear-gradient(135deg, #f8d7da 0%, #f5c6cb 100%);
            border-left: 4px solid #dc3545;
        }

        .permission-tabs {
            display: flex;
            gap: 10px;
            margin-bottom: 20px;
            border-bottom: 2px solid #e9ecef;
        }

        .permission-tab {
            padding: 10px 20px;
            border: none;
            background: none;
            cursor: pointer;
            border-bottom: 3px solid transparent;
            font-weight: 500;
            transition: all 0.3s ease;
        }

        .permission-tab.active {
            border-bottom-color: #667eea;
            color: #667eea;
        }

        .permission-tab:hover {
            background: #f8f9fa;
        }

        .statistics-grid {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
            gap: 20px;
            margin: 20px 0;
        }

        .stat-card {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            padding: 20px;
            border-radius: 15px;
            text-align: center;
            box-shadow: 0 8px 25px rgba(102, 126, 234, 0.3);
        }

        .stat-number {
            font-size: 2rem;
            font-weight: 700;
            margin-bottom: 8px;
        }

        .stat-label {
            font-size: 0.9rem;
            opacity: 0.9;
        }

        .comparison-table {
            width: 100%;
            border-collapse: collapse;
            margin: 20px 0;
            background: white;
            border-radius: 12px;
            overflow: hidden;
            box-shadow: 0 4px 15px rgba(0,0,0,0.1);
        }

        .comparison-table th,
        .comparison-table td {
            padding: 12px;
            text-align: center;
            border-bottom: 1px solid #e9ecef;
        }

        .comparison-table th {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            font-weight: 600;
        }

        .trend-visualization {
            position: relative;
            height: 200px;
            margin: 20px 0;
            background: linear-gradient(to right, #e8f5e8, #fff3e0, #ffebee);
            border-radius: 15px;
            padding: 20px;
        }

        /* 权限升级演示样式 */
        .upgrade-demo-controls {
            background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
            border-radius: 15px;
            padding: 20px;
            margin-bottom: 25px;
            color: white;
        }

        .upgrade-control-section h5 {
            color: white;
            margin-bottom: 15px;
            text-align: center;
            font-size: 1.1rem;
            text-shadow: 1px 1px 2px rgba(0,0,0,0.3);
        }

        .upgrade-buttons {
            display: flex;
            justify-content: center;
            gap: 15px;
            flex-wrap: wrap;
        }

        .upgrade-buttons .btn {
            min-width: 160px;
            padding: 10px 15px;
            font-weight: 600;
            border-radius: 25px;
            transition: all 0.3s ease;
            box-shadow: 0 4px 15px rgba(0,0,0,0.1);
        }

        .upgrade-buttons .btn:hover {
            transform: translateY(-2px);
            box-shadow: 0 8px 25px rgba(0,0,0,0.2);
        }

        .role-hierarchy-path {
            background: rgba(255,255,255,0.98);
            border-radius: 15px;
            padding: 25px;
            margin-bottom: 25px;
            box-shadow: 0 8px 30px rgba(0,0,0,0.1);
        }

        .role-hierarchy-path h5 {
            color: #333;
            margin-bottom: 20px;
            text-align: center;
            font-size: 1.1rem;
        }

        .hierarchy-visualization {
            position: relative;
            min-height: 200px;
            background: linear-gradient(135deg, #e3f2fd 0%, #f3e5f5 50%, #fff3e0 100%);
            border-radius: 12px;
            padding: 20px;
            overflow-x: auto;
        }

        .role-hierarchy-chain {
            display: flex;
            align-items: center;
            justify-content: space-between;
            min-width: 800px;
            position: relative;
        }

        .role-hierarchy-item {
            display: flex;
            flex-direction: column;
            align-items: center;
            position: relative;
            z-index: 2;
        }

        .role-item {
            width: 120px;
            height: 120px;
            border-radius: 50%;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            font-size: 2rem;
            cursor: pointer;
            transition: all 0.4s ease;
            box-shadow: 0 6px 20px rgba(0,0,0,0.15);
            position: relative;
        }

        .role-item.level-1 { background: linear-gradient(135deg, #ffab91 0%, #ff8a65 100%); }
        .role-item.level-2 { background: linear-gradient(135deg, #81c784 0%, #66bb6a 100%); }
        .role-item.level-3 { background: linear-gradient(135deg, #64b5f6 0%, #42a5f5 100%); }
        .role-item.level-4 { background: linear-gradient(135deg, #ba68c8 0%, #ab47bc 100%); }
        .role-item.level-5 { background: linear-gradient(135deg, #ffd54f 0%, #ffca28 100%); }

        .role-item:hover {
            transform: scale(1.1) translateY(-5px);
            box-shadow: 0 12px 35px rgba(0,0,0,0.25);
        }

        .role-item.active {
            transform: scale(1.2) translateY(-8px);
            box-shadow: 0 15px 40px rgba(0,0,0,0.3);
            border: 4px solid #fff;
        }

        .role-name {
            font-size: 0.8rem;
            font-weight: 600;
            margin-top: 10px;
            text-align: center;
            color: #333;
            min-height: 40px;
        }

        .role-permissions {
            font-size: 0.7rem;
            color: #666;
            text-align: center;
            margin-top: 5px;
        }

        .upgrade-arrow {
            font-size: 2rem;
            color: #ff6b6b;
            z-index: 1;
            animation: pulse 2s infinite;
        }

        @keyframes pulse {
            0%, 100% { transform: scale(1); opacity: 0.7; }
            50% { transform: scale(1.2); opacity: 1; }
        }

        .permission-animation-area {
            background: rgba(255,255,255,0.98);
            border-radius: 15px;
            padding: 25px;
            margin-bottom: 25px;
            box-shadow: 0 8px 30px rgba(0,0,0,0.1);
        }

        .permission-animation-area h5 {
            color: #333;
            margin-bottom: 20px;
            text-align: center;
            font-size: 1.1rem;
        }

        .animation-container {
            min-height: 150px;
            background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
            border-radius: 12px;
            padding: 20px;
            position: relative;
            overflow: hidden;
        }

        .permission-matrix-animation {
            display: grid;
            grid-template-columns: repeat(4, 1fr);
            gap: 10px;
            margin-bottom: 15px;
        }

        .animated-permission-cell {
            aspect-ratio: 1;
            border-radius: 8px;
            display: flex;
            align-items: center;
            justify-content: center;
            font-weight: bold;
            font-size: 0.8rem;
            color: white;
            transition: all 0.6s cubic-bezier(0.4, 0, 0.2, 1);
            transform: scale(0);
        }

        .animated-permission-cell.animate-in {
            transform: scale(1);
            animation: slideInScale 0.6s ease-out forwards;
        }

        .animated-permission-cell.level-1 { background: #ff5722; }
        .animated-permission-cell.level-2 { background: #ff9800; }
        .animated-permission-cell.level-3 { background: #4caf50; }
        .animated-permission-cell.level-4 { background: #2196f3; }

        @keyframes slideInScale {
            0% { 
                transform: scale(0) rotate(-45deg);
                opacity: 0;
            }
            60% {
                transform: scale(1.1) rotate(5deg);
                opacity: 0.8;
            }
            100% { 
                transform: scale(1) rotate(0deg);
                opacity: 1;
            }
        }

        .upgrade-impact-stats {
            background: rgba(255,255,255,0.98);
            border-radius: 15px;
            padding: 25px;
            margin-bottom: 25px;
            box-shadow: 0 8px 30px rgba(0,0,0,0.1);
        }

        .upgrade-impact-stats h5 {
            color: #333;
            margin-bottom: 20px;
            text-align: center;
            font-size: 1.1rem;
        }

        .stats-grid {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
            gap: 20px;
        }

        .stat-card {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            padding: 20px;
            border-radius: 12px;
            text-align: center;
            box-shadow: 0 6px 20px rgba(102, 126, 234, 0.3);
            transition: transform 0.3s ease;
        }

        .stat-card:hover {
            transform: translateY(-5px);
        }

        .stat-value {
            font-size: 2rem;
            font-weight: bold;
            display: block;
            margin-bottom: 5px;
            text-shadow: 2px 2px 4px rgba(0,0,0,0.3);
        }

        .stat-label {
            font-size: 0.9rem;
            opacity: 0.9;
        }

        .role-details-panel {
            background: rgba(255,255,255,0.98);
            border-radius: 15px;
            padding: 25px;
            box-shadow: 0 8px 30px rgba(0,0,0,0.1);
        }

        .role-details-panel h5 {
            color: #333;
            margin-bottom: 20px;
            text-align: center;
            font-size: 1.1rem;
        }

        .role-details-content {
            min-height: 100px;
        }

        .role-detail-card {
            background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
            color: white;
            padding: 20px;
            border-radius: 12px;
            margin-bottom: 15px;
        }

        .role-detail-card h6 {
            font-size: 1.1rem;
            margin-bottom: 10px;
            text-shadow: 1px 1px 2px rgba(0,0,0,0.3);
        }

        .upgrade-suggestion {
            background: rgba(255,255,255,0.2);
            padding: 15px;
            border-radius: 8px;
            margin-top: 15px;
            border-left: 4px solid rgba(255,255,255,0.5);
        }

        /* ========== 角色层次结构响应式优化 ========== */
        @media (max-width: 480px) {
            .role-hierarchy-chain {
                flex-direction: column;
                min-width: auto;
                gap: 15px;
            }

            .upgrade-arrow {
                transform: rotate(90deg);
                font-size: 1.2rem;
            }

            .role-item {
                width: 80px;
                height: 80px;
                font-size: 1.2rem;
            }

            .upgrade-buttons {
                flex-direction: column;
                align-items: center;
                gap: 10px;
            }

            .upgrade-buttons .btn {
                min-width: 160px;
                font-size: 0.9rem;
            }
        }

        @media (min-width: 481px) and (max-width: 768px) {
            .role-hierarchy-chain {
                flex-direction: column;
                min-width: auto;
                gap: 18px;
            }

            .upgrade-arrow {
                transform: rotate(90deg);
            }

            .role-item {
                width: 90px;
                height: 90px;
                font-size: 1.4rem;
            }

            .upgrade-buttons {
                flex-direction: column;
                align-items: center;
                gap: 12px;
            }

            .upgrade-buttons .btn {
                min-width: 180px;
            }
        }

        @media (min-width: 769px) and (max-width: 1024px) {
            .role-hierarchy-chain {
                gap: 25px;
            }

            .role-item {
                width: 100px;
                height: 100px;
                font-size: 1.5rem;
            }
        }

        /* ========== 矩阵可视化响应式优化 ========== */
        @media (max-width: 480px) {
            .matrix-visualization-container {
                grid-template-columns: 1fr;
                gap: 15px;
            }

            .heatmap-container {
                font-size: 0.7rem;
                overflow-x: auto;
                -webkit-overflow-scrolling: touch;
            }

            .heatmap-cell {
                padding: 6px 4px;
                min-height: 30px;
                min-width: 50px;
            }

            .heatmap-header {
                font-size: 0.65rem;
                padding: 8px 4px;
            }
        }

        @media (min-width: 481px) and (max-width: 768px) {
            .matrix-visualization-container {
                grid-template-columns: 1fr;
                gap: 18px;
            }

            .heatmap-container {
                font-size: 0.75rem;
            }

            .heatmap-cell {
                padding: 7px 5px;
                min-height: 32px;
            }
        }

        @media (min-width: 769px) and (max-width: 1024px) {
            .matrix-visualization-container {
                grid-template-columns: 1fr;
                gap: 20px;
            }

            .heatmap-container {
                font-size: 0.8rem;
            }

            .heatmap-cell {
                padding: 8px 6px;
                min-height: 35px;
            }
        }

        @media (min-width: 1025px) and (max-width: 1440px) {
            .matrix-visualization-container {
                grid-template-columns: 1fr 1fr;
                gap: 25px;
            }
        }

        /* ========== 触摸友好性增强 ========== */
        @media (max-width: 1024px) {
            /* 增加触摸目标大小 */
            .btn-nav,
            .phase-item,
            .scope-mode-btn {
                min-height: 44px;
                min-width: 44px;
            }

            /* 增加间距以避免误触 */
            .scope-options {
                gap: 20px;
            }

            /* 优化滚动条 */
            .permission-matrix {
                -webkit-overflow-scrolling: touch;
            }

            /* 提升交互反馈 */
            .scope-option:active {
                transform: translateY(-2px) scale(0.98);
            }

            .btn:active {
                transform: translateY(1px) scale(0.98);
            }
        }

        /* ==================== 增强动画系统 ==================== */
        
        /* 页面加载动画 */
        @keyframes fadeInUp {
            from {
                opacity: 0;
                transform: translateY(30px);
            }
            to {
                opacity: 1;
                transform: translateY(0);
            }
        }

        @keyframes slideInLeft {
            from {
                opacity: 0;
                transform: translateX(-30px);
            }
            to {
                opacity: 1;
                transform: translateX(0);
            }
        }

        @keyframes slideInRight {
            from {
                opacity: 0;
                transform: translateX(30px);
            }
            to {
                opacity: 1;
                transform: translateX(0);
            }
        }

        /* 应用页面加载动画 */
        .header {
            animation: fadeInUp 0.8s ease-out;
        }

        .feature-highlight {
            animation: fadeInUp 0.8s ease-out 0.2s both;
        }

        .phase-navigation {
            animation: fadeInUp 0.8s ease-out 0.4s both;
        }

        .auth-section {
            animation: slideInLeft 0.8s ease-out 0.6s both;
        }

        .main-content > .content-card:first-child {
            animation: slideInLeft 0.8s ease-out 0.8s both;
        }

        .main-content > .content-card:last-child {
            animation: slideInRight 0.8s ease-out 0.8s both;
        }

        /* 交互元素悬浮动画增强 */
        .scope-option:hover {
            transition: all 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275);
            transform: translateY(-8px) scale(1.02);
            box-shadow: 
                0 15px 40px rgba(102, 126, 234, 0.25),
                0 5px 15px rgba(0, 0, 0, 0.1);
        }

        .scope-option.selected {
            animation: selectPulse 0.6s ease-out;
            position: relative;
        }

        .scope-option.selected::after {
            content: '✓';
            position: absolute;
            top: 10px;
            right: 15px;
            background: #28a745;
            color: white;
            width: 24px;
            height: 24px;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 12px;
            font-weight: bold;
            animation: checkmarkPop 0.3s ease-out;
        }

        @keyframes selectPulse {
            0% {
                transform: scale(1);
            }
            50% {
                transform: scale(1.05);
            }
            100% {
                transform: scale(1.02);
            }
        }

        @keyframes checkmarkPop {
            0% {
                transform: scale(0);
                opacity: 0;
            }
            50% {
                transform: scale(1.2);
                opacity: 1;
            }
            100% {
                transform: scale(1);
                opacity: 1;
            }
        }

        /* 按钮悬浮效果增强 */
        .btn-primary {
            position: relative;
            overflow: hidden;
            transition: all 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
        }

        .btn-primary::before {
            content: '';
            position: absolute;
            top: 0;
            left: -100%;
            width: 100%;
            height: 100%;
            background: linear-gradient(90deg, transparent, rgba(255,255,255,0.2), transparent);
            transition: left 0.5s ease;
        }

        .btn-primary:hover::before {
            left: 100%;
        }

        .btn-primary:hover {
            transform: translateY(-3px);
            box-shadow: 
                0 12px 30px rgba(102, 126, 234, 0.4),
                0 4px 15px rgba(0, 0, 0, 0.1);
        }

        /* 表格交互增强 */
        .matrix-table tr {
            transition: all 0.3s ease;
        }

        .matrix-table tr:hover {
            background: rgba(102, 126, 234, 0.08);
            transform: scale(1.01);
        }

        .matrix-table td:hover {
            transform: scale(1.1);
            z-index: 10;
            position: relative;
            border-radius: 8px;
            box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
        }

        /* 加载状态 */
        .loading-spinner {
            display: inline-block;
            width: 20px;
            height: 20px;
            border: 3px solid #f3f3f3;
            border-top: 3px solid #667eea;
            border-radius: 50%;
            animation: spin 1s linear infinite;
        }

        @keyframes spin {
            0% { transform: rotate(0deg); }
            100% { transform: rotate(360deg); }
        }

        /* 状态动画 */
        .status-success {
            animation: successPulse 0.6s ease-out;
        }

        .status-error {
            animation: errorShake 0.6s ease-out;
        }

        @keyframes successPulse {
            0% {
                background-color: #d4edda;
                transform: scale(1);
            }
            50% {
                background-color: #c3e6cb;
                transform: scale(1.02);
            }
            100% {
                background-color: #d4edda;
                transform: scale(1);
            }
        }

        @keyframes errorShake {
            0%, 100% {
                transform: translateX(0);
            }
            10%, 30%, 50%, 70%, 90% {
                transform: translateX(-5px);
            }
            20%, 40%, 60%, 80% {
                transform: translateX(5px);
            }
        }

        /* 无障碍和性能优化 */
        @media (prefers-reduced-motion: reduce) {
            *,
            *::before,
            *::after {
                animation-duration: 0.01ms !important;
                animation-iteration-count: 1 !important;
                transition-duration: 0.01ms !important;
            }
        }

        /* 高对比度模式 */
        @media (prefers-contrast: high) {
            .content-card,
            .scope-option,
            .btn-primary {
                border: 2px solid #000;
            }
        }

        /* 高对比度模式手动切换 */
        .high-contrast {
            filter: contrast(200%) brightness(120%);
        }

        .high-contrast .content-card {
            background: white;
            border: 3px solid #000;
            color: #000;
        }

        .high-contrast .btn-primary {
            background: #000;
            color: #fff;
            border: 3px solid #000;
        }

        .high-contrast .scope-option {
            background: white;
            border: 3px solid #000;
            color: #000;
        }

        .high-contrast .scope-option.selected {
            background: #000;
            color: #fff;
        }

        /* 表单验证样式增强 */
        .form-control.is-valid {
            border-color: #28a745;
            box-shadow: 0 0 0 3px rgba(40, 167, 69, 0.1);
        }

        .form-control.is-invalid {
            border-color: #dc3545;
            box-shadow: 0 0 0 3px rgba(220, 53, 69, 0.1);
        }

        .restored-from-draft {
            background: linear-gradient(90deg, #e3f2fd, transparent);
            animation: draftRestoreGlow 2s ease-out;
        }

        @keyframes draftRestoreGlow {
            0% {
                background: #e3f2fd;
                box-shadow: 0 0 0 3px rgba(33, 150, 243, 0.3);
            }
            100% {
                background: transparent;
                box-shadow: none;
            }
        }

        /* 淡出动画 */
        @keyframes fadeOut {
            from {
                opacity: 1;
                transform: translateY(0);
            }
            to {
                opacity: 0;
                transform: translateY(-10px);
            }
        }

        /* 网络状态指示器动画 */
        #networkStatus {
            animation: statusSlideIn 0.5s ease-out;
        }

        @keyframes statusSlideIn {
            from {
                transform: translateX(100px);
                opacity: 0;
            }
            to {
                transform: translateX(0);
                opacity: 1;
            }
        }

        /* 对比度切换按钮悬浮效果 */
        button[title*="对比度"]:hover {
            transform: scale(1.1) rotate(15deg);
            box-shadow: 0 8px 25px rgba(102, 126, 234, 0.3);
        }

        /* 用户指南样式 */
        #userGuide .guide-header {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            padding: 20px;
            border-radius: 16px 16px 0 0;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }

        #userGuide .guide-header h3 {
            margin: 0;
            font-size: 1.3rem;
        }

        #userGuide .guide-close {
            background: none;
            border: none;
            color: white;
            font-size: 1.5rem;
            cursor: pointer;
            padding: 5px;
            border-radius: 50%;
            width: 35px;
            height: 35px;
            display: flex;
            align-items: center;
            justify-content: center;
            transition: all 0.3s ease;
        }

        #userGuide .guide-close:hover {
            background: rgba(255, 255, 255, 0.2);
            transform: rotate(90deg);
        }

        #userGuide .guide-content {
            padding: 25px;
            max-height: 50vh;
            overflow-y: auto;
        }

        #userGuide .guide-section {
            margin-bottom: 25px;
        }

        #userGuide .guide-section:last-child {
            margin-bottom: 0;
        }

        #userGuide .guide-section h4 {
            margin: 0 0 12px 0;
            color: #333;
            font-size: 1.1rem;
            padding-bottom: 8px;
            border-bottom: 2px solid #f0f0f0;
        }

        #userGuide .guide-section ul {
            margin: 0;
            padding-left: 20px;
            color: #555;
        }

        #userGuide .guide-section li {
            margin-bottom: 8px;
            line-height: 1.5;
        }

        #userGuide .guide-section li:last-child {
            margin-bottom: 0;
        }

        #userGuide kbd {
            background: #f8f9fa;
            border: 1px solid #dee2e6;
            border-radius: 4px;
            padding: 2px 6px;
            font-family: 'Courier New', monospace;
            font-size: 0.9em;
            color: #495057;
            box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
        }

        #userGuide strong {
            color: #667eea;
        }

        /* scaleIn 动画 */
        @keyframes scaleIn {
            from {
                opacity: 0;
                transform: translate(-50%, -50%) scale(0.8);
            }
            to {
                opacity: 1;
                transform: translate(-50%, -50%) scale(1);
            }
        }

        /* 指南按钮悬浮效果 */
        button[title*="指南"]:hover {
            transform: scale(1.1);
            box-shadow: 0 8px 25px rgba(23, 162, 184, 0.3);
            background: #e3f2fd;
        }

        /* 移动端用户指南适配 */
        @media (max-width: 768px) {
            #userGuide {
                max-width: 95vw;
                max-height: 85vh;
                transform: translate(-50%, -50%);
            }
            
            #userGuide .guide-header {
                padding: 15px;
            }
            
            #userGuide .guide-header h3 {
                font-size: 1.1rem;
            }
            
            #userGuide .guide-content {
                padding: 20px;
                max-height: 60vh;
            }
            
            #userGuide .guide-section {
                margin-bottom: 20px;
            }
            
            button[title*="指南"] {
                bottom: 70px;
                right: 15px;
                width: 45px;
                height: 45px;
            }
        }
    </style>
</head>
<body>
    <div class="container">
        <!-- 页面头部 -->
        <div class="header">
            <h1>🎯 智能通知系统</h1>
            <div class="subtitle">Phase 6: 通知范围权限中心 - 5角色×4范围×4级别权限控制演示</div>
            
            <!-- 核心功能突出展示 -->
            <div class="feature-highlight">
                <h3>🎯 核心特色：4级通知范围精准控制系统</h3>
                <div class="feature-list">
                    <div class="feature-item">
                        🏫 <strong>SCHOOL_WIDE</strong> - 全校范围通知控制
                    </div>
                    <div class="feature-item">
                        🏢 <strong>DEPARTMENT</strong> - 部门范围权限管理
                    </div>
                    <div class="feature-item">
                        🎓 <strong>CLASS</strong> - 班级范围精准投放
                    </div>
                    <div class="feature-item">
                        📚 <strong>GRADE</strong> - 年级范围智能控制
                    </div>
                    <div class="feature-item">
                        👥 <strong>5个角色</strong> - 校长/教务主任/教师/班主任/学生
                    </div>
                    <div class="feature-item">
                        ⚖️ <strong>80种权限组合</strong> - 5×4×4完整权限矩阵
                    </div>
                </div>
            </div>
            
            <!-- 阶段导航 -->
            <div class="phase-navigation">
                <div class="phase-item completed" onclick="navigateToPhase('phase1')" style="cursor: pointer;">
                    <span>✅</span>
                    <span>Phase 1: 连接测试</span>
                </div>
                <span class="phase-arrow">→</span>
                <div class="phase-item completed" onclick="navigateToPhase('phase2')" style="cursor: pointer;">
                    <span>✅</span>
                    <span>Phase 2: 身份认证</span>
                </div>
                <span class="phase-arrow">→</span>
                <div class="phase-item completed" onclick="navigateToPhase('phase3')" style="cursor: pointer;">
                    <span>✅</span>
                    <span>Phase 3: 通知发布</span>
                </div>
                <span class="phase-arrow">→</span>
                <div class="phase-item completed" onclick="navigateToPhase('phase4')" style="cursor: pointer;">
                    <span>✅</span>
                    <span>Phase 4: 通知列表</span>
                </div>
                <span class="phase-arrow">→</span>
                <div class="phase-item completed" onclick="navigateToPhase('phase5')" style="cursor: pointer;">
                    <span>✅</span>
                    <span>Phase 5: 审批工作流</span>
                </div>
                <span class="phase-arrow">→</span>
                <div class="phase-item active">
                    <span>🎯</span>
                    <span>Phase 6: 范围权限中心</span>
                </div>
                <span class="phase-arrow">→</span>
                <div class="phase-item pending">
                    <span>⭕</span>
                    <span>Phase 7: 完整集成</span>
                </div>
            </div>
        </div>

        <!-- 认证区域 -->
        <div class="auth-section" id="authSection">
            <div class="auth-toggle">
                <h3 id="authTitle">🔑 角色认证与权限切换</h3>
                <button class="btn btn-secondary" id="toggleAuthBtn" onclick="toggleAuthSection()" style="display: none;">
                    收起/展开
                </button>
            </div>
            
            <div id="authForm">
                <div class="auth-form">
                    <div class="form-group">
                        <label for="roleSelect">选择演示角色 <span style="color: red;">*</span></label>
                        <select class="form-control" id="roleSelect">
                            <option value="PRINCIPAL">🎩 校长 (全部4个范围权限)</option>
                            <option value="ACADEMIC_ADMIN" selected>👔 教务主任 (3个范围权限)</option>
                            <option value="TEACHER">👨‍🏫 教师 (2个范围权限)</option>
                            <option value="CLASS_TEACHER">👩‍🏫 班主任 (2个范围权限)</option>
                            <option value="STUDENT">🎓 学生 (1个范围权限)</option>
                        </select>
                    </div>
                    
                    <div class="form-group">
                        <label>认证状态</label>
                        <div id="authStatus" style="padding: 12px; border-radius: 8px; background: #f8f9fa; color: #6c757d;">
                            未认证
                        </div>
                    </div>
                    
                    <div class="form-group">
                        <button class="btn btn-primary" id="authenticateBtn" onclick="authenticateInPage()">
                            🚀 一键认证
                        </button>
                    </div>
                </div>
                
                <!-- 权限说明 -->
                <div class="alert alert-info" style="margin-top: 20px;">
                    <strong>🎯 Phase 6 - 真实API集成演示说明：</strong><br>
                    <div style="margin: 10px 0;">
                        <strong>🔥 新特性：完整后端API集成</strong><br>
                        • <strong>/api/available-scopes</strong>：动态获取用户真实可用范围权限<br>
                        • <strong>/api/scope-test</strong>：执行真实的范围权限测试验证<br>
                        • <strong>双重认证流程</strong>：Mock School API → JWT Token → 主服务API<br>
                        • <strong>智能错误处理</strong>：API失败时自动切换到本地配置
                    </div>
                    <div style="margin: 10px 0; padding: 10px; background: rgba(255,193,7,0.1); border-left: 3px solid #ffc107; border-radius: 4px;">
                        <strong>📊 角色权限分布：</strong><br>
                        <strong>校长</strong>：4个范围 (SCHOOL_WIDE + DEPARTMENT + CLASS + GRADE) |
                        <strong>教务主任</strong>：3个范围 (SCHOOL_WIDE + DEPARTMENT + GRADE) |
                        <strong>教师</strong>：2个范围 (DEPARTMENT + CLASS) |
                        <strong>班主任</strong>：2个范围 (CLASS + GRADE) |
                        <strong>学生</strong>：1个范围 (CLASS)
                    </div>
                    <strong>💡 使用步骤：</strong>
                    选择角色 → 一键认证 → 观察API动态权限获取 → 选择范围 → 执行权限测试
                </div>
            </div>
        </div>

        <!-- 主内容区域 -->
        <div class="main-content d-none" id="mainContent">
            <!-- 左侧：权限矩阵和测试区域 -->
            <div class="content-card">
                <div class="card-title" id="mainCardTitle">
                    🎯 通知范围权限控制中心
                </div>
                
                <!-- 权限矩阵表格 -->
                <div class="permission-matrix" id="permissionMatrixSection">
                    <div class="permission-tabs">
                        <button class="permission-tab active" onclick="switchMatrixView('table')" id="tableTab">
                            📋 表格视图
                        </button>
                        <button class="permission-tab" onclick="switchMatrixView('heatmap')" id="heatmapTab">
                            🔥 热力图
                        </button>
                        <button class="permission-tab" onclick="switchMatrixView('charts')" id="chartsTab">
                            📊 图表分析
                        </button>
                        <button class="permission-tab" onclick="switchMatrixView('comparison')" id="comparisonTab">
                            ⚖️ 权限对比
                        </button>
                        <button class="permission-tab" onclick="switchMatrixView('upgrade')" id="upgradeTab">
                            🚀 权限升级演示
                        </button>
                    </div>

                    <!-- 表格视图 -->
                    <div id="tableView" class="matrix-view">
                        <h4 style="margin-bottom: 20px; color: #333; display: flex; align-items: center; gap: 10px;">
                            📊 5角色×4范围权限矩阵
                            <span id="matrixUpdateIndicator" style="font-size: 0.8rem; color: #666;"></span>
                        </h4>
                        <div id="permissionMatrixTable">
                            <!-- 权限矩阵表格将在这里动态生成 -->
                        </div>
                    </div>

                    <!-- 热力图视图 -->
                    <div id="heatmapView" class="matrix-view" style="display: none;">
                        <h4 style="margin-bottom: 20px; color: #333; text-align: center;">
                            🔥 权限热力图 - 5角色×4范围×4级别可视化
                        </h4>
                        <div id="permissionHeatmap">
                            <!-- 权限热力图将在这里动态生成 -->
                        </div>
                        <div style="margin-top: 20px; text-align: center; font-size: 0.9rem; color: #666;">
                            💡 提示：颜色越深表示权限级别越多，点击单元格查看详细权限信息
                        </div>
                    </div>

                    <!-- 图表分析视图 -->
                    <div id="chartsView" class="matrix-view" style="display: none;">
                        <h4 style="margin-bottom: 20px; color: #333; text-align: center;">
                            📊 权限统计图表分析
                        </h4>
                        
                        <!-- 统计卡片 -->
                        <div class="statistics-grid" id="statisticsGrid">
                            <!-- 统计数据将在这里动态生成 -->
                        </div>

                        <!-- 图表容器 -->
                        <div class="matrix-visualization-container">
                            <div class="chart-container">
                                <div class="chart-title">📊 角色权限分布</div>
                                <canvas id="rolePermissionChart"></canvas>
                            </div>
                            <div class="chart-container">
                                <div class="chart-title">🎯 范围覆盖统计</div>
                                <canvas id="scopeCoverageChart"></canvas>
                            </div>
                            <div class="chart-container">
                                <div class="chart-title">📈 权限层级趋势</div>
                                <canvas id="permissionTrendChart"></canvas>
                            </div>
                            <div class="chart-container">
                                <div class="chart-title">⭕ 权限组合分析</div>
                                <canvas id="combinationAnalysisChart"></canvas>
                            </div>
                        </div>
                    </div>

                    <!-- 权限对比视图 -->
                    <div id="comparisonView" class="matrix-view" style="display: none;">
                        <h4 style="margin-bottom: 20px; color: #333; text-align: center;">
                            ⚖️ 角色权限深度对比分析
                        </h4>
                        <div id="permissionComparison">
                            <!-- 权限对比表格将在这里动态生成 -->
                        </div>
                    </div>

                    <!-- 权限升级演示视图 -->
                    <div id="upgradeView" class="matrix-view" style="display: none;">
                        <h4 style="margin-bottom: 20px; color: #333; text-align: center;">
                            🚀 权限升级演示中心 - 从学生到校长的权限进化路径
                        </h4>
                        
                        <!-- 升级演示控制面板 -->
                        <div class="upgrade-demo-controls">
                            <div class="upgrade-control-section">
                                <h5>🎮 演示控制</h5>
                                <div class="upgrade-buttons">
                                    <button class="btn btn-success" onclick="startAutomaticUpgradeDemo()">
                                        🎬 自动演示升级路径
                                    </button>
                                    <button class="btn btn-info" onclick="showUpgradeSimulator()">
                                        🧪 升级模拟器
                                    </button>
                                    <button class="btn btn-warning" onclick="compareAllRoles()">
                                        📊 全角色权限对比
                                    </button>
                                    <button class="btn btn-secondary" onclick="resetUpgradeDemo()">
                                        🔄 重置演示
                                    </button>
                                </div>
                            </div>
                        </div>

                        <!-- 角色升级路径图 -->
                        <div class="role-hierarchy-path" id="roleHierarchyPath">
                            <h5>🎯 角色权限升级路径图</h5>
                            <div class="hierarchy-visualization" id="hierarchyVisualization">
                                <!-- 升级路径图将在这里动态生成 -->
                            </div>
                        </div>

                        <!-- 权限变化动画区域 -->
                        <div class="permission-animation-area" id="permissionAnimationArea">
                            <h5>✨ 权限变化动画演示</h5>
                            <div class="animation-container" id="animationContainer">
                                <!-- 动画演示将在这里显示 -->
                            </div>
                        </div>

                        <!-- 升级效果统计 -->
                        <div class="upgrade-impact-stats" id="upgradeImpactStats">
                            <h5>📊 权限升级影响分析</h5>
                            <div class="stats-grid" id="upgradeStatsGrid">
                                <!-- 升级统计将在这里显示 -->
                            </div>
                        </div>

                        <!-- 角色详情和升级建议 -->
                        <div class="role-details-panel" id="roleDetailsPanel">
                            <h5>👤 角色详情与升级建议</h5>
                            <div class="role-details-content" id="roleDetailsContent">
                                <!-- 角色详情将在这里显示 -->
                            </div>
                        </div>
                    </div>
                </div>

                <!-- 范围选择器 - 增强版本 -->
                <div class="scope-selector" id="scopeSelectorSection" style="display: none;">
                    <div class="scope-selector-controls">
                        <div>
                            <h4 style="margin: 0; color: #333; display: flex; align-items: center; gap: 10px;">
                                🎯 交互式范围权限选择器
                                <span id="availableScopeCount" style="font-size: 0.9rem; color: #666;"></span>
                            </h4>
                        </div>
                        <div class="scope-mode-toggle">
                            <button class="scope-mode-btn active" id="singleModeBtn" onclick="setScopeSelectionMode('single')">
                                📍 单选模式
                            </button>
                            <button class="scope-mode-btn" id="multiModeBtn" onclick="setScopeSelectionMode('multi')">
                                🎯 多选模式
                            </button>
                        </div>
                    </div>
                    
                    <!-- 选择摘要 -->
                    <div class="scope-selection-summary" id="scopeSelectionSummary" style="display: none;">
                        <div class="scope-selection-count" id="selectionCount">0</div>
                        <div class="scope-selection-label">个范围已选择</div>
                        <div style="margin-top: 10px; font-size: 0.9rem;" id="selectionDetails"></div>
                    </div>
                    
                    <!-- 范围选项网格 -->
                    <div class="scope-options" id="scopeOptions">
                        <!-- 范围选项将在这里动态生成 -->
                    </div>
                    
                    <!-- 操作按钮组 -->
                    <div style="display: flex; justify-content: center; gap: 15px; flex-wrap: wrap; margin-top: 25px;">
                        <button class="btn btn-primary" id="testScopePermission" onclick="testSelectedScopePermissions()" disabled>
                            🧪 测试选中权限
                        </button>
                        <button class="btn btn-info" onclick="refreshAvailableScopes()">
                            🔄 刷新可用范围
                        </button>
                        <button class="btn btn-warning" onclick="showScopeExplanation()">
                            📖 范围说明
                        </button>
                        <button class="btn btn-secondary" onclick="clearAllSelections()">
                            🗑️ 清空选择
                        </button>
                        <button class="btn btn-success" onclick="selectAllAvailable()">
                            ✅ 全选可用
                        </button>
                    </div>
                    
                    <!-- 权限级别详情展示 -->
                    <div id="scopePermissionDetails" style="display: none; margin-top: 25px; padding: 20px; background: #f8f9fa; border-radius: 15px;">
                        <h5 style="margin-bottom: 15px; color: #333; display: flex; align-items: center; gap: 8px;">
                            📋 权限级别详情
                        </h5>
                        <div id="permissionDetailsContent">
                            <!-- 权限详情将在这里动态生成 -->
                        </div>
                    </div>
                </div>

                <!-- 权限边界测试系统 -->
                <div class="permission-boundary-testing" id="boundaryTestingSection" style="display: none;">
                    <div class="testing-header">
                        <div class="testing-title">
                            🧪 权限边界实时测试系统
                            <span id="testingSubtitle" style="font-size: 0.8rem; font-weight: 400; opacity: 0.9;">智能权限验证与分析平台</span>
                        </div>
                        <div class="test-mode-selector">
                            <button class="test-mode-btn active" id="singleTestMode" onclick="switchTestMode('single')">
                                🎯 单项测试
                            </button>
                            <button class="test-mode-btn" id="batchTestMode" onclick="switchTestMode('batch')">
                                📊 批量测试
                            </button>
                            <button class="test-mode-btn" id="pressureTestMode" onclick="switchTestMode('pressure')">
                                ⚡ 压力测试
                            </button>
                        </div>
                    </div>

                    <!-- 测试场景选择 -->
                    <div id="testScenarioSection">
                        <div style="margin-bottom: 15px; font-size: 1rem; font-weight: 600;">📋 选择测试场景：</div>
                        <div class="test-scenario-grid" id="testScenarioGrid">
                            <!-- 测试场景将动态生成 -->
                        </div>
                    </div>

                    <!-- 批量测试控制 -->
                    <div class="batch-test-controls">
                        <div style="display: flex; gap: 10px; align-items: center;">
                            <button class="btn btn-success" id="startBoundaryTest" onclick="startBoundaryTest()" disabled>
                                🚀 开始边界测试
                            </button>
                            <button class="btn btn-info" onclick="resetBoundaryTest()">
                                🔄 重置测试
                            </button>
                            <button class="btn btn-warning" onclick="exportTestReport()">
                                📊 导出报告
                            </button>
                        </div>
                        <div style="font-size: 0.9rem; opacity: 0.8;" id="testSelectionInfo">
                            请选择测试场景
                        </div>
                    </div>
                </div>

                <!-- 测试进度显示 -->
                <div class="test-progress-container" id="testProgressContainer">
                    <div class="test-progress-header">
                        <div style="font-weight: 600; color: #333;">🔄 测试执行进度</div>
                        <div id="testProgressText">0/0</div>
                    </div>
                    <div class="test-progress-bar">
                        <div class="test-progress-fill" id="testProgressFill" style="width: 0%;">0%</div>
                    </div>
                    <div class="test-progress-stats" id="testProgressStats">
                        <!-- 进度统计将动态生成 -->
                    </div>
                </div>

                <!-- 实时测试结果 -->
                <div class="realtime-results" id="realtimeResults" style="display: none;">
                    <div style="padding: 15px 20px; border-bottom: 2px solid #e9ecef; background: #f8f9fa; font-weight: 600; color: #333;">
                        📈 实时测试结果
                        <span id="resultsCount" style="font-size: 0.8rem; font-weight: 400; color: #666; margin-left: 10px;">0 项结果</span>
                    </div>
                    <div id="resultsContainer">
                        <!-- 实时结果项将在这里显示 -->
                    </div>
                </div>

                <!-- 测试报告 -->
                <div class="test-report" id="testReport">
                    <div class="report-header">
                        <div class="report-title">📊 权限边界测试报告</div>
                        <div class="report-export">
                            <button class="export-btn" onclick="exportReportAsCSV()">📄 CSV</button>
                            <button class="export-btn" onclick="exportReportAsJSON()">📋 JSON</button>
                            <button class="export-btn" onclick="printTestReport()">🖨️ 打印</button>
                        </div>
                    </div>

                    <div class="report-summary" id="reportSummary">
                        <!-- 报告摘要卡片将动态生成 -->
                    </div>

                    <div class="report-details">
                        <div class="report-section">
                            <div class="section-title">🎯 测试覆盖范围</div>
                            <div id="coverageDetails"><!-- 覆盖范围详情 --></div>
                        </div>

                        <div class="report-section">
                            <div class="section-title">⚖️ API vs 本地配置对比</div>
                            <div class="comparison-matrix">
                                <table class="comparison-table" id="comparisonTable">
                                    <!-- 对比表格将动态生成 -->
                                </table>
                            </div>
                        </div>

                        <div class="report-section">
                            <div class="section-title">📈 性能统计</div>
                            <div id="performanceStats"><!-- 性能统计详情 --></div>
                        </div>

                        <div class="report-section">
                            <div class="section-title">🔍 异常发现</div>
                            <div id="anomalyDetails"><!-- 异常详情 --></div>
                        </div>
                    </div>
                </div>

                <!-- 测试结果展示 -->
                <div class="test-results d-none" id="testResultsSection">
                    <h4 style="margin-bottom: 15px; color: #333;">🧪 权限测试结果</h4>
                    <div id="testResultsContent">
                        <!-- 测试结果将在这里显示 -->
                    </div>
                </div>
            </div>
            
            <!-- 右侧：用户信息和控制面板 -->
            <div>
                <!-- 当前用户信息 -->
                <div class="content-card">
                    <div class="card-title">👤 当前用户</div>
                    <div class="user-info" id="userInfo">
                        <!-- 用户信息将在这里动态生成 -->
                    </div>
                </div>
                
                <!-- 范围权限详情 -->
                <div class="content-card">
                    <div class="card-title">🎯 范围权限详情</div>
                    <div class="permission-info">
                        <div class="permission-title">当前角色范围权限：</div>
                        <ul class="permission-list" id="scopePermissionList">
                            <!-- 范围权限列表将在这里动态生成 -->
                        </ul>
                    </div>
                </div>
                
                <!-- 快速操作面板 -->
                <div class="content-card">
                    <div class="card-title">⚡ 快速操作</div>
                    <div style="display: grid; gap: 10px;">
                        <button class="btn btn-info" onclick="switchToNextRole()">
                            🔄 切换下一角色
                        </button>
                        <button class="btn btn-success" onclick="testAllScopePermissions()">
                            🧪 测试所有范围
                        </button>
                        <button class="btn btn-primary" onclick="showBoundaryTestingSystem()">
                            🎯 权限边界测试
                        </button>
                        <button class="btn btn-warning" onclick="showPermissionComparison()">
                            📊 权限对比
                        </button>
                        <button class="btn btn-secondary" onclick="exportPermissionMatrix()">
                            📄 导出权限矩阵
                        </button>
                    </div>
                </div>
            </div>
        </div>

        <!-- 测试日志 -->
        <div class="content-card">
            <div class="card-title">📋 操作日志</div>
            <div class="log-container" id="testLog">
                <div style="color: #666;">等待用户操作...</div>
            </div>
        </div>

        <!-- 导航区域 -->
        <div class="navigation-section">
            <a href="phase5-notification-approval.html" class="btn-nav">
                ← 返回 Phase 5: 审批工作流
            </a>
            <a href="#" class="btn-nav" id="nextPhaseBtn" style="display: none;">
                进入 Phase 7: 完整集成 →
            </a>
        </div>
    </div>

    <!-- Chart.js for advanced visualizations -->
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
    <script>
        // 全局变量
        const API_BASE = 'http://localhost:48081';
        const MOCK_API_BASE = 'http://localhost:48082';
        let currentUser = null;
        let currentToken = null;
        let currentAvailableScopes = [];
        let currentSelectedScopes = []; // 改为数组支持多选
        let scopeSelectionMode = 'single'; // 'single' 或 'multi'
        
        // 权限边界测试系统变量
        let testingMode = 'single'; // 'single', 'batch', 'pressure'
        let selectedTestScenarios = [];
        let boundaryTestResults = [];
        let testExecutionStats = {
            total: 0,
            completed: 0,
            passed: 0,
            failed: 0,
            errors: 0,
            startTime: null,
            endTime: null,
            avgResponseTime: 0
        };
        let isTestingInProgress = false;
        
        // =======================================================
        // ================== 🔒 安全工具函数 ===================
        // =======================================================
        
        // 安全的元素创建函数，避免XSS攻击
        function createSafeElement(tagName, textContent = '', className = '') {
            const element = document.createElement(tagName);
            if (textContent) {
                element.textContent = textContent; // 使用textContent而不是innerHTML
            }
            if (className) {
                element.className = className;
            }
            return element;
        }
        
        // HTML转义函数，防止XSS攻击
        function escapeHtml(unsafe) {
            if (typeof unsafe !== 'string') return unsafe;
            return unsafe
                .replace(/&/g, "&amp;")
                .replace(/</g, "&lt;")
                .replace(/>/g, "&gt;")
                .replace(/"/g, "&quot;")
                .replace(/'/g, "&#039;");
        }
        
        // 验证和清理字符串输入
        function sanitizeInput(input) {
            if (typeof input !== 'string') return '';
            // 移除潜在的恶意字符
            return input.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '')
                       .replace(/javascript:/gi, '')
                       .replace(/on\w+\s*=/gi, '')
                       .trim();
        }
        
        // 验证API响应数据的安全性
        function validateApiResponse(data) {
            if (!data || typeof data !== 'object') {
                return false;
            }
            
            // 递归验证对象中的字符串值
            function validateValue(value) {
                if (typeof value === 'string') {
                    // 检查是否包含潜在的恶意脚本
                    const dangerousPatterns = [
                        /<script/i,
                        /javascript:/i,
                        /on\w+\s*=/i,
                        /eval\(/i,
                        /expression\(/i
                    ];
                    return !dangerousPatterns.some(pattern => pattern.test(value));
                }
                
                if (typeof value === 'object' && value !== null) {
                    if (Array.isArray(value)) {
                        return value.every(validateValue);
                    } else {
                        return Object.values(value).every(validateValue);
                    }
                }
                
                return true;
            }
            
            return validateValue(data);
        }
        
        // 安全的API调用封装
        async function safeApiCall(url, options = {}) {
            try {
                const response = await fetch(url, options);
                const data = await response.json();
                
                // 验证响应数据安全性
                if (!validateApiResponse(data)) {
                    throw new Error('API响应包含不安全的内容');
                }
                
                return data;
            } catch (error) {
                console.error('安全API调用失败:', error);
                throw error;
            }
        }
        
        // 范围权限配置矩阵 - 修正为与数据库一致
        const SCOPE_PERMISSION_MATRIX = {
            'PRINCIPAL': ['SCHOOL_WIDE', 'DEPARTMENT', 'CLASS', 'GRADE'],
            'ACADEMIC_ADMIN': ['SCHOOL_WIDE', 'DEPARTMENT', 'GRADE'],
            'TEACHER': ['DEPARTMENT', 'CLASS'],
            'CLASS_TEACHER': ['CLASS', 'GRADE'],
            'STUDENT': ['CLASS']
        };

        // 范围映射：前端显示名称 → 数据库字段名称
        const SCOPE_MAPPING = {
            'SCHOOL_WIDE': 'ALL_SCHOOL',
            'DEPARTMENT': 'DEPARTMENT', 
            'CLASS': 'CLASS',
            'GRADE': 'GRADE'
        };

        // 角色对应的测试账号
        const roleAccounts = {
            'PRINCIPAL': {
                employeeId: 'PRINCIPAL_001',
                name: 'Principal-Zhang',
                password: 'admin123',
                displayName: '校长张明'
            },
            'ACADEMIC_ADMIN': {
                employeeId: 'ACADEMIC_ADMIN_001', 
                name: 'Director-Li',
                password: 'admin123',
                displayName: '教务主任李华'
            },
            'TEACHER': {
                employeeId: 'TEACHER_001',
                name: 'Teacher-Wang',
                password: 'admin123',
                displayName: '教师王老师'
            },
            'CLASS_TEACHER': {
                employeeId: 'CLASS_TEACHER_001',
                name: 'ClassTeacher-Liu',
                password: 'admin123',
                displayName: '班主任刘老师'
            },
            'STUDENT': {
                employeeId: 'STUDENT_001',
                name: 'Student-Zhang',
                password: 'admin123',
                displayName: '学生张同学'
            }
        };

        // 范围配置信息
        const scopeConfig = {
            'SCHOOL_WIDE': {
                icon: '🏫',
                title: '全校范围',
                description: '面向全校师生的重要通知',
                color: '#e74c3c'
            },
            'DEPARTMENT': {
                icon: '🏢',
                title: '部门范围',
                description: '部门内部工作通知',
                color: '#f39c12'
            },
            'CLASS': {
                icon: '🎓',
                title: '班级范围',
                description: '班级内部学习生活通知',
                color: '#3498db'
            },
            'GRADE': {
                icon: '📚',
                title: '年级范围',
                description: '年级统一管理通知',
                color: '#27ae60'
            }
        };

        // 通知级别定义（新增）
        const NOTIFICATION_LEVELS = {
            1: { name: '紧急通知', color: '#ff6b6b', icon: '🚨', description: '需要立即处理的重要事件' },
            2: { name: '重要通知', color: '#feca57', icon: '⚠️', description: '重要但不紧急的工作事项' },
            3: { name: '常规通知', color: '#48dbfb', icon: 'ℹ️', description: '日常工作和学习相关信息' },
            4: { name: '提醒通知', color: '#1dd1a1', icon: '💡', description: '温馨提示和生活服务信息' }
        };

        // 增强的权限矩阵：5角色×4范围×4级别 = 80种组合（新增）
        const ENHANCED_PERMISSION_MATRIX = {
            'PRINCIPAL': {
                'SCHOOL_WIDE': [1, 2, 3, 4],    // 校长：全校范围所有级别
                'DEPARTMENT': [1, 2, 3, 4],     // 校长：部门范围所有级别
                'CLASS': [1, 2, 3, 4],          // 校长：班级范围所有级别
                'GRADE': [1, 2, 3, 4]           // 校长：年级范围所有级别
            },
            'ACADEMIC_ADMIN': {
                'SCHOOL_WIDE': [2, 3, 4],       // 教务主任：全校范围2-4级（1级需审批）
                'DEPARTMENT': [2, 3, 4],        // 教务主任：部门范围2-4级
                'CLASS': [],                    // 教务主任：无班级范围权限
                'GRADE': [2, 3, 4]              // 教务主任：年级范围2-4级
            },
            'TEACHER': {
                'SCHOOL_WIDE': [],              // 教师：无全校范围权限
                'DEPARTMENT': [3],              // 教师：部门范围3级（根据数据库配置修正）
                'CLASS': [3, 4],                // 教师：班级范围3-4级（根据数据库配置修正）
                'GRADE': []                     // 教师：无年级范围权限
            },
            'CLASS_TEACHER': {
                'SCHOOL_WIDE': [],              // 班主任：无全校范围权限
                'DEPARTMENT': [],               // 班主任：无部门范围权限
                'CLASS': [3, 4],                // 班主任：班级范围3-4级（根据数据库配置）
                'GRADE': [3, 4]                 // 班主任：年级范围3-4级（推理权限）
            },
            'STUDENT': {
                'SCHOOL_WIDE': [],              // 学生：无全校范围权限
                'DEPARTMENT': [],               // 学生：无部门范围权限
                'CLASS': [4],                   // 学生：班级范围4级（查看权限，根据数据库配置）
                'GRADE': []                     // 学生：无年级范围权限
            }
        };

        // 当前矩阵视图模式
        let currentMatrixView = 'table';

        // Chart.js实例存储
        let chartInstances = {};
        
        // 权限边界测试场景定义
        const BOUNDARY_TEST_SCENARIOS = {
            positive: {
                title: '正向权限测试',
                icon: '✅',
                description: '测试用户应该拥有的权限，验证正常权限路径',
                color: '#28a745',
                generateTests: function(role) {
                    const tests = [];
                    const rolePermissions = ENHANCED_PERMISSION_MATRIX[role] || {};
                    Object.keys(rolePermissions).forEach(scope => {
                        const levels = rolePermissions[scope] || [];
                        levels.forEach(level => {
                            tests.push({
                                role: role,
                                scope: scope,
                                level: level,
                                expected: 'ALLOWED',
                                type: 'positive',
                                description: `${roleAccounts[role]?.displayName}应该能在${scopeConfig[scope]?.title}发布${NOTIFICATION_LEVELS[level]?.name}`
                            });
                        });
                    });
                    return tests;
                }
            },
            negative: {
                title: '负向权限测试',
                icon: '❌',
                description: '测试用户不应该拥有的权限，验证权限限制',
                color: '#dc3545',
                generateTests: function(role) {
                    const tests = [];
                    const rolePermissions = ENHANCED_PERMISSION_MATRIX[role] || {};
                    const allScopes = ['SCHOOL_WIDE', 'DEPARTMENT', 'CLASS', 'GRADE'];
                    const allLevels = [1, 2, 3, 4];
                    
                    allScopes.forEach(scope => {
                        const allowedLevels = rolePermissions[scope] || [];
                        allLevels.forEach(level => {
                            if (!allowedLevels.includes(level)) {
                                tests.push({
                                    role: role,
                                    scope: scope,
                                    level: level,
                                    expected: 'DENIED',
                                    type: 'negative',
                                    description: `${roleAccounts[role]?.displayName}不应该能在${scopeConfig[scope]?.title}发布${NOTIFICATION_LEVELS[level]?.name}`
                                });
                            }
                        });
                    });
                    return tests;
                }
            },
            boundary: {
                title: '边界条件测试',
                icon: '⚖️',
                description: '测试权限边界临界点，验证审批流程',
                color: '#ffc107',
                generateTests: function(role) {
                    const tests = [];
                    // 教务主任的1级全校通知需要审批
                    if (role === 'ACADEMIC_ADMIN') {
                        tests.push({
                            role: role,
                            scope: 'SCHOOL_WIDE',
                            level: 1,
                            expected: 'PENDING_APPROVAL',
                            type: 'boundary',
                            description: '教务主任发布1级全校通知需要校长审批'
                        });
                    }
                    
                    // 跨角色权限边界测试
                    const roleHierarchy = ['STUDENT', 'CLASS_TEACHER', 'TEACHER', 'ACADEMIC_ADMIN', 'PRINCIPAL'];
                    const currentIndex = roleHierarchy.indexOf(role);
                    
                    if (currentIndex > 0) {
                        // 测试越权行为
                        const higherRole = roleHierarchy[currentIndex + 1];
                        if (higherRole && ENHANCED_PERMISSION_MATRIX[higherRole]) {
                            Object.keys(ENHANCED_PERMISSION_MATRIX[higherRole]).forEach(scope => {
                                const higherLevels = ENHANCED_PERMISSION_MATRIX[higherRole][scope] || [];
                                const currentLevels = ENHANCED_PERMISSION_MATRIX[role][scope] || [];
                                
                                higherLevels.forEach(level => {
                                    if (!currentLevels.includes(level)) {
                                        tests.push({
                                            role: role,
                                            scope: scope,
                                            level: level,
                                            expected: 'DENIED',
                                            type: 'boundary',
                                            description: `${roleAccounts[role]?.displayName}尝试越权执行${roleAccounts[higherRole]?.displayName}的权限`
                                        });
                                    }
                                });
                            });
                        }
                    }
                    
                    return tests;
                }
            },
            stress: {
                title: '压力极限测试',
                icon: '⚡',
                description: '高并发权限验证，测试系统稳定性',
                color: '#17a2b8',
                generateTests: function(role) {
                    const tests = [];
                    const baseTest = {
                        role: role,
                        scope: 'CLASS',
                        level: 4,
                        expected: 'ALLOWED',
                        type: 'stress',
                        description: '高频权限验证请求测试'
                    };
                    
                    // 生成多个相同的测试用于压力测试
                    for (let i = 0; i < 20; i++) {
                        tests.push({
                            ...baseTest,
                            id: `stress_${i}`,
                            description: `压力测试 #${i + 1}: 快速权限验证`
                        });
                    }
                    return tests;
                }
            },
            edge: {
                title: '边缘场景测试',
                icon: '🔍',
                description: '异常输入和边缘情况处理测试',
                color: '#6f42c1',
                generateTests: function(role) {
                    return [
                        {
                            role: role,
                            scope: 'INVALID_SCOPE',
                            level: 1,
                            expected: 'ERROR',
                            type: 'edge',
                            description: '无效范围处理测试'
                        },
                        {
                            role: role,
                            scope: 'CLASS',
                            level: 999,
                            expected: 'ERROR',
                            type: 'edge',
                            description: '无效级别处理测试'
                        },
                        {
                            role: 'INVALID_ROLE',
                            scope: 'CLASS',
                            level: 1,
                            expected: 'ERROR',
                            type: 'edge',
                            description: '无效角色处理测试'
                        }
                    ];
                }
            }
        };

        // 页面加载完成后的初始化
        document.addEventListener('DOMContentLoaded', function() {
            try {
                addLog('🎯 Phase 6: 通知范围权限中心页面已加载', 'info');
                addLog('💡 请选择角色并认证，然后体验5×4×4权限矩阵可视化功能', 'info');
                
                // 初始化增强用户体验功能
                initializeEnhancedUX();
                
                // 初始化权限矩阵表格
                initializePermissionMatrix();
                
                // 初始化权限边界测试系统
                initializeBoundaryTestingSystem();
                
                // 检测来自其他Phase的跳转
                const urlParams = new URLSearchParams(window.location.search);
                if (urlParams.get('from')) {
                    addLog(`🔄 检测到从${urlParams.get('from')}跳转，尝试继承认证状态`, 'info');
                    inheritAuthFromPreviousPhase();
                }
                
            } catch (initError) {
                console.error('页面初始化错误:', initError);
                addLog(`❌页面初始化发生错误: ${initError.message}`, 'error');
            }
        });

        // 初始化增强用户体验功能
        function initializeEnhancedUX() {
            // 1. 添加键盘快捷键支持
            document.addEventListener('keydown', function(e) {
                // Alt + L: 快速登录
                if (e.altKey && e.key === 'l') {
                    e.preventDefault();
                    document.getElementById('employeeId')?.focus();
                    addLog('⌨️ 快捷键：Alt+L 快速定位到登录表单', 'info');
                }
                
                // Alt + T: 快速范围测试
                if (e.altKey && e.key === 't') {
                    e.preventDefault();
                    const testBtn = document.getElementById('testScopeButton');
                    if (testBtn && !testBtn.disabled) {
                        testBtn.click();
                        addLog('⌨️ 快捷键：Alt+T 执行范围测试', 'info');
                    }
                }
                
                // Escape: 取消选择所有范围
                if (e.key === 'Escape') {
                    clearAllScopeSelections();
                    addLog('⌨️ 快捷键：Esc 清除所有范围选择', 'info');
                }
            });

            // 2. 添加智能表单验证
            const formInputs = document.querySelectorAll('.form-control');
            formInputs.forEach(input => {
                // 实时验证
                input.addEventListener('input', function() {
                    validateInputRealTime(this);
                });
                
                // 失去焦点时验证
                input.addEventListener('blur', function() {
                    validateInputComplete(this);
                });
            });

            // 3. 添加范围选择智能提示
            initializeScopeSelectionHints();

            // 4. 添加自动保存功能（草稿）
            initializeAutoSave();

            // 5. 添加网络状态检测
            initializeNetworkStatus();

            // 6. 添加无障碍功能增强
            initializeAccessibilityEnhancements();

            addLog('✨ 增强用户体验功能已初始化完成', 'success');
        }

        // 实时表单验证
        function validateInputRealTime(input) {
            const value = input.value.trim();
            const fieldName = input.id;
            
            // 移除之前的验证样式
            input.classList.remove('is-valid', 'is-invalid');
            
            if (value.length > 0) {
                switch(fieldName) {
                    case 'employeeId':
                        if (value.length >= 3) {
                            input.classList.add('is-valid');
                            showFieldHint(input, '✓ 工号格式正确');
                        } else {
                            showFieldHint(input, '工号至少需要3个字符');
                        }
                        break;
                    case 'name':
                        if (value.length >= 2) {
                            input.classList.add('is-valid');
                            showFieldHint(input, '✓ 姓名格式正确');
                        } else {
                            showFieldHint(input, '姓名至少需要2个字符');
                        }
                        break;
                    case 'password':
                        if (value.length >= 6) {
                            input.classList.add('is-valid');
                            showFieldHint(input, '✓ 密码强度良好');
                        } else {
                            showFieldHint(input, '密码至少需要6个字符');
                        }
                        break;
                }
            }
        }

        // 完整表单验证
        function validateInputComplete(input) {
            const value = input.value.trim();
            if (value.length === 0) {
                input.classList.add('is-invalid');
                showFieldHint(input, '此字段不能为空', 'error');
            }
        }

        // 显示字段提示
        function showFieldHint(input, message, type = 'info') {
            const existingHint = input.parentNode.querySelector('.field-hint');
            if (existingHint) {
                existingHint.remove();
            }
            
            const hint = document.createElement('div');
            hint.className = `field-hint field-hint-${type}`;
            hint.textContent = message;
            hint.style.cssText = `
                font-size: 0.8rem;
                margin-top: 4px;
                padding: 4px 8px;
                border-radius: 4px;
                background: ${type === 'error' ? '#f8d7da' : type === 'success' ? '#d4edda' : '#e2e3e5'};
                color: ${type === 'error' ? '#721c24' : type === 'success' ? '#155724' : '#383d41'};
                border: 1px solid ${type === 'error' ? '#f5c6cb' : type === 'success' ? '#c3e6cb' : '#ced4da'};
                animation: fadeInUp 0.3s ease;
            `;
            
            input.parentNode.appendChild(hint);
            
            // 3秒后自动移除成功提示
            if (type !== 'error') {
                setTimeout(() => {
                    if (hint.parentNode) {
                        hint.remove();
                    }
                }, 3000);
            }
        }

        // 范围选择智能提示
        function initializeScopeSelectionHints() {
            const scopeOptions = document.querySelectorAll('.scope-option');
            
            scopeOptions.forEach(option => {
                option.addEventListener('mouseenter', function() {
                    if (!this.classList.contains('disabled')) {
                        showScopeTooltip(this);
                    }
                });
                
                option.addEventListener('mouseleave', function() {
                    hideScopeTooltip();
                });
            });
        }

        // 显示范围提示
        function showScopeTooltip(element) {
            const scopeType = element.dataset.scope;
            const tooltip = document.createElement('div');
            tooltip.className = 'scope-tooltip';
            tooltip.innerHTML = getScopeTooltipContent(scopeType);
            
            tooltip.style.cssText = `
                position: fixed;
                z-index: 1000;
                background: rgba(0, 0, 0, 0.9);
                color: white;
                padding: 12px 16px;
                border-radius: 8px;
                font-size: 0.9rem;
                max-width: 300px;
                pointer-events: none;
                box-shadow: 0 8px 25px rgba(0, 0, 0, 0.3);
                animation: fadeInUp 0.3s ease;
            `;
            
            document.body.appendChild(tooltip);
            positionTooltip(tooltip, element);
            
            // 5秒后自动隐藏
            setTimeout(() => {
                if (tooltip.parentNode) {
                    tooltip.remove();
                }
            }, 5000);
        }

        // 隐藏范围提示
        function hideScopeTooltip() {
            const tooltip = document.querySelector('.scope-tooltip');
            if (tooltip) {
                tooltip.style.animation = 'fadeOut 0.3s ease';
                setTimeout(() => {
                    if (tooltip.parentNode) {
                        tooltip.remove();
                    }
                }, 300);
            }
        }

        // 获取范围提示内容
        function getScopeTooltipContent(scopeType) {
            const tooltips = {
                'SCHOOL_WIDE': '🏫 <strong>全校通知</strong><br>影响所有师生，需要最高权限',
                'DEPARTMENT': '🏢 <strong>部门通知</strong><br>仅限特定部门内部查看',
                'CLASS': '📚 <strong>班级通知</strong><br>针对特定班级的通知',
                'GRADE': '📊 <strong>年级通知</strong><br>覆盖整个年级的通知'
            };
            return tooltips[scopeType] || '范围信息不可用';
        }

        // 定位提示框
        function positionTooltip(tooltip, element) {
            const rect = element.getBoundingClientRect();
            const tooltipRect = tooltip.getBoundingClientRect();
            
            let top = rect.bottom + 10;
            let left = rect.left + (rect.width / 2) - (tooltipRect.width / 2);
            
            // 边界检测
            if (left < 10) left = 10;
            if (left + tooltipRect.width > window.innerWidth - 10) {
                left = window.innerWidth - tooltipRect.width - 10;
            }
            if (top + tooltipRect.height > window.innerHeight - 10) {
                top = rect.top - tooltipRect.height - 10;
            }
            
            tooltip.style.top = top + 'px';
            tooltip.style.left = left + 'px';
        }

        // 清除所有范围选择
        function clearAllScopeSelections() {
            const selectedOptions = document.querySelectorAll('.scope-option.selected');
            selectedOptions.forEach(option => {
                option.classList.remove('selected');
                option.classList.add('status-error');
                setTimeout(() => {
                    option.classList.remove('status-error');
                }, 600);
            });
        }

        // 自动保存功能
        function initializeAutoSave() {
            const formData = {};
            const inputs = document.querySelectorAll('.form-control');
            
            inputs.forEach(input => {
                input.addEventListener('input', function() {
                    formData[this.id] = this.value;
                    localStorage.setItem('phase6_draft', JSON.stringify(formData));
                });
            });

            // 恢复草稿
            const savedDraft = localStorage.getItem('phase6_draft');
            if (savedDraft) {
                try {
                    const draft = JSON.parse(savedDraft);
                    Object.keys(draft).forEach(key => {
                        const input = document.getElementById(key);
                        if (input && draft[key]) {
                            input.value = draft[key];
                            input.classList.add('restored-from-draft');
                        }
                    });
                    addLog('📝 已恢复之前保存的表单草稿', 'info');
                } catch (e) {
                    console.warn('恢复草稿失败:', e);
                }
            }
        }

        // 网络状态检测
        function initializeNetworkStatus() {
            function updateNetworkStatus() {
                const isOnline = navigator.onLine;
                const statusElement = document.getElementById('networkStatus');
                
                if (!statusElement) {
                    const status = document.createElement('div');
                    status.id = 'networkStatus';
                    status.style.cssText = `
                        position: fixed;
                        top: 10px;
                        right: 10px;
                        z-index: 1001;
                        padding: 8px 16px;
                        border-radius: 20px;
                        font-size: 0.8rem;
                        font-weight: 600;
                        transition: all 0.3s ease;
                    `;
                    document.body.appendChild(status);
                }
                
                const status = document.getElementById('networkStatus');
                if (isOnline) {
                    status.textContent = '🌐 在线';
                    status.style.background = '#d4edda';
                    status.style.color = '#155724';
                    status.style.border = '1px solid #c3e6cb';
                } else {
                    status.textContent = '📡 离线';
                    status.style.background = '#f8d7da';
                    status.style.color = '#721c24';
                    status.style.border = '1px solid #f5c6cb';
                }
            }

            window.addEventListener('online', updateNetworkStatus);
            window.addEventListener('offline', updateNetworkStatus);
            updateNetworkStatus();
        }

        // 无障碍功能增强
        function initializeAccessibilityEnhancements() {
            // 为所有交互元素添加键盘导航支持
            const interactiveElements = document.querySelectorAll('button, .scope-option, .phase-item');
            interactiveElements.forEach(element => {
                if (!element.tabIndex) {
                    element.tabIndex = 0;
                }
                
                element.addEventListener('keydown', function(e) {
                    if (e.key === 'Enter' || e.key === ' ') {
                        e.preventDefault();
                        this.click();
                    }
                });
            });

            // 添加高对比度切换
            const contrastToggle = document.createElement('button');
            contrastToggle.innerHTML = '🔆';
            contrastToggle.title = '切换高对比度模式';
            contrastToggle.style.cssText = `
                position: fixed;
                bottom: 20px;
                right: 20px;
                z-index: 1001;
                width: 50px;
                height: 50px;
                border-radius: 50%;
                border: 2px solid #667eea;
                background: white;
                font-size: 1.2rem;
                cursor: pointer;
                box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
                transition: all 0.3s ease;
            `;
            
            contrastToggle.addEventListener('click', function() {
                document.body.classList.toggle('high-contrast');
                this.innerHTML = document.body.classList.contains('high-contrast') ? '🔅' : '🔆';
                addLog(document.body.classList.contains('high-contrast') ? 
                    '🔅 已启用高对比度模式' : '🔆 已关闭高对比度模式', 'info');
            });
            
            document.body.appendChild(contrastToggle);

            // 添加用户指南按钮
            const guideToggle = document.createElement('button');
            guideToggle.innerHTML = '❓';
            guideToggle.title = '显示/隐藏用户指南';
            guideToggle.style.cssText = `
                position: fixed;
                bottom: 80px;
                right: 20px;
                z-index: 1001;
                width: 50px;
                height: 50px;
                border-radius: 50%;
                border: 2px solid #17a2b8;
                background: white;
                font-size: 1.2rem;
                cursor: pointer;
                box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
                transition: all 0.3s ease;
            `;
            
            guideToggle.addEventListener('click', function() {
                toggleUserGuide();
            });
            
            document.body.appendChild(guideToggle);
        }

        // 用户指南系统
        function toggleUserGuide() {
            const existingGuide = document.getElementById('userGuide');
            if (existingGuide) {
                existingGuide.remove();
                return;
            }

            const guide = document.createElement('div');
            guide.id = 'userGuide';
            guide.innerHTML = `
                <div class="guide-header">
                    <h3>📚 Phase 6 用户指南</h3>
                    <button class="guide-close" onclick="document.getElementById('userGuide').remove()">✕</button>
                </div>
                <div class="guide-content">
                    <div class="guide-section">
                        <h4>⌨️ 快捷键</h4>
                        <ul>
                            <li><kbd>Alt + L</kbd> - 快速定位到登录表单</li>
                            <li><kbd>Alt + T</kbd> - 执行范围权限测试</li>
                            <li><kbd>Esc</kbd> - 清除所有范围选择</li>
                            <li><kbd>Tab</kbd> - 键盘导航</li>
                        </ul>
                    </div>
                    <div class="guide-section">
                        <h4>🎯 主要功能</h4>
                        <ul>
                            <li>🔐 <strong>双重认证</strong> - 支持工号+姓名+密码登录</li>
                            <li>📊 <strong>权限矩阵</strong> - 5×4×4权限可视化</li>
                            <li>🎯 <strong>范围控制</strong> - 4级通知范围管理</li>
                            <li>🔍 <strong>边界测试</strong> - 权限边界自动检测</li>
                        </ul>
                    </div>
                    <div class="guide-section">
                        <h4>💡 使用提示</h4>
                        <ul>
                            <li>鼠标悬浮在范围选项上可查看详细说明</li>
                            <li>表单支持自动保存草稿功能</li>
                            <li>支持打印和高对比度模式</li>
                            <li>所有功能均支持键盘操作</li>
                        </ul>
                    </div>
                    <div class="guide-section">
                        <h4>📱 设备支持</h4>
                        <ul>
                            <li>📱 手机端：320px - 768px</li>
                            <li>📟 平板端：768px - 1024px</li>
                            <li>💻 桌面端：1024px+</li>
                            <li>🖥️ 大屏幕：1440px+ 优化</li>
                        </ul>
                    </div>
                </div>
            `;
            
            guide.style.cssText = `
                position: fixed;
                top: 50%;
                left: 50%;
                transform: translate(-50%, -50%);
                z-index: 2000;
                background: white;
                border-radius: 16px;
                box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
                max-width: 500px;
                max-height: 80vh;
                overflow-y: auto;
                animation: scaleIn 0.3s ease-out;
            `;
            
            document.body.appendChild(guide);
            
            // 添加背景遮罩
            const overlay = document.createElement('div');
            overlay.style.cssText = `
                position: fixed;
                top: 0;
                left: 0;
                width: 100%;
                height: 100%;
                background: rgba(0, 0, 0, 0.5);
                z-index: 1999;
                backdrop-filter: blur(5px);
            `;
            overlay.onclick = () => guide.remove();
            document.body.appendChild(overlay);
            
            // 当guide被删除时，也删除overlay
            const observer = new MutationObserver(function(mutations) {
                mutations.forEach(function(mutation) {
                    mutation.removedNodes.forEach(function(node) {
                        if (node === guide && overlay.parentNode) {
                            overlay.remove();
                            observer.disconnect();
                        }
                    });
                });
            });
            observer.observe(document.body, { childList: true });
        }

        // 初始化权限矩阵表格
        function initializePermissionMatrix() {
            addLog('📊 初始化权限矩阵表格...', 'info');
            
            try {
                const container = document.getElementById('permissionMatrixTable');
                if (!container) {
                    throw new Error('权限矩阵表格容器不存在');
                }

                // 构建权限矩阵表格HTML
                const roles = Object.keys(SCOPE_PERMISSION_MATRIX);
                const scopes = ['SCHOOL_WIDE', 'DEPARTMENT', 'CLASS', 'GRADE'];
                
                let tableHTML = `
                    <table class="matrix-table">
                        <thead>
                            <tr>
                                <th>角色 / 范围</th>
                `;
                
                // 表头：范围列
                scopes.forEach(scope => {
                    const config = scopeConfig[scope];
                    tableHTML += `<th>${config.icon}<br>${config.title}</th>`;
                });
                
                tableHTML += `
                            </tr>
                        </thead>
                        <tbody>
                `;
                
                // 表格内容：角色权限矩阵
                roles.forEach(role => {
                    const rolePermissions = ENHANCED_PERMISSION_MATRIX[role] || {};
                    const roleDisplay = roleAccounts[role]?.displayName || role;
                    const roleIcon = getRoleIcon(role);
                    
                    tableHTML += `
                        <tr>
                            <td style="background: #f8f9fa; font-weight: 600;">
                                ${roleIcon} ${roleDisplay}
                            </td>
                    `;
                    
                    scopes.forEach(scope => {
                        const allowedLevels = rolePermissions[scope] || [];
                        const hasPermission = allowedLevels.length > 0;
                        const cellClass = hasPermission ? 'permission-allowed' : 'permission-denied';
                        const cellContent = hasPermission ? 
                            `✅ ${allowedLevels.length}级权限` : 
                            '❌ 无权限';
                        
                        tableHTML += `
                            <td class="${cellClass}" 
                                onclick="showPermissionDetail('${role}', '${scope}', ${hasPermission})"
                                data-role="${role}" data-scope="${scope}"
                                title="${roleDisplay} - ${scopeConfig[scope].title}: ${hasPermission ? allowedLevels.map(l => NOTIFICATION_LEVELS[l].name).join('、') : '无权限'}">
                                <div class="permission-cell">${cellContent}</div>
                            </td>
                        `;
                    });
                    
                    tableHTML += `</tr>`;
                });
                
                tableHTML += `
                        </tbody>
                    </table>
                `;
                
                // 安全的DOM操作，避免XSS
                container.innerHTML = ''; // 清空现有内容
                const tempDiv = document.createElement('div');
                tempDiv.innerHTML = tableHTML;
                while (tempDiv.firstChild) {
                    container.appendChild(tempDiv.firstChild);
                }
                addLog('✅ 权限矩阵表格初始化完成', 'success');
                
                // 更新指示器
                const indicator = document.getElementById('matrixUpdateIndicator');
                if (indicator) {
                    const totalCombinations = roles.length * scopes.length;
                    let validCombinations = 0;
                    let totalLevels = 0;
                    
                    roles.forEach(role => {
                        scopes.forEach(scope => {
                            const levels = ENHANCED_PERMISSION_MATRIX[role]?.[scope] || [];
                            if (levels.length > 0) {
                                validCombinations++;
                                totalLevels += levels.length;
                            }
                        });
                    });
                    
                    // 安全的文本更新，避免XSS
                    indicator.textContent = '';
                    const span = createSafeElement('span', 
                        `(${roles.length}角色×${scopes.length}范围×4级别=${totalCombinations}种组合，${validCombinations}种有效，${totalLevels}个权限级别)`);
                    span.style.color = '#28a745';
                    indicator.appendChild(span);
                }
                
            } catch (error) {
                addLog(`❌ 初始化权限矩阵表格失败: ${error.message}`, 'error');
            }
        }

        // 获取角色图标
        function getRoleIcon(role) {
            const icons = {
                'PRINCIPAL': '🎩',
                'ACADEMIC_ADMIN': '👔',
                'TEACHER': '👨‍🏫',
                'CLASS_TEACHER': '👩‍🏫',
                'STUDENT': '🎓'
            };
            return icons[role] || '👤';
        }

        // 显示权限详情（增强版本，支持级别详情）
        function showPermissionDetail(role, scope, hasPermission) {
            const roleDisplay = roleAccounts[role]?.displayName || role;
            const scopeTitle = scopeConfig[scope]?.title || scope;
            const allowedLevels = ENHANCED_PERMISSION_MATRIX[role]?.[scope] || [];
            
            showPermissionDetailModal(role, scope, roleDisplay, scopeTitle, allowedLevels);
            addLog(`🔍 查看详细权限信息: ${roleDisplay} - ${scopeTitle}`, 'info');
        }

        // 显示权限详情模态框（新增）
        function showPermissionDetailModal(role, scope, roleDisplay, scopeTitle, allowedLevels) {
            // 创建模态框
            let modal = document.getElementById('permissionDetailModal');
            if (!modal) {
                modal = document.createElement('div');
                modal.id = 'permissionDetailModal';
                modal.className = 'permission-detail-modal';
                document.body.appendChild(modal);
            }

            const hasPermission = allowedLevels.length > 0;
            const totalLevels = Object.keys(NOTIFICATION_LEVELS).length;
            
            let levelDetailsHtml = '';
            for (let level = 1; level <= 4; level++) {
                const levelInfo = NOTIFICATION_LEVELS[level];
                const hasThisLevel = allowedLevels.includes(level);
                const statusClass = hasThisLevel ? 'level-detail-allowed' : 'level-detail-denied';
                const statusIcon = hasThisLevel ? '✅' : '❌';
                const statusText = hasThisLevel ? '允许发布' : '无权发布';
                
                levelDetailsHtml += `
                    <div class="level-detail-item ${statusClass}">
                        <div style="display: flex; align-items: center; gap: 10px;">
                            <span style="font-size: 1.2rem;">${levelInfo.icon}</span>
                            <div>
                                <div style="font-weight: 600; color: ${levelInfo.color};">
                                    ${level}级 - ${levelInfo.name}
                                </div>
                                <div style="font-size: 0.9rem; opacity: 0.8;">
                                    ${levelInfo.description}
                                </div>
                            </div>
                        </div>
                        <div style="display: flex; align-items: center; gap: 8px; font-weight: 600;">
                            <span>${statusIcon}</span>
                            <span>${statusText}</span>
                        </div>
                    </div>
                `;
            }

            // 安全的模态框创建，避免XSS
            modal.innerHTML = ''; // 清空内容
            const modalContent = createSafeElement('div', '', 'permission-detail-content');
            
            // 创建标题区域
            const headerDiv = createSafeElement('div');
            headerDiv.style.cssText = 'display: flex; justify-content: space-between; align-items: center; margin-bottom: 25px;';
            
            const titleH3 = createSafeElement('h3', `${getRoleIcon(role)} 权限详情分析`);
            titleH3.style.cssText = 'margin: 0; color: #333; display: flex; align-items: center; gap: 10px;';
            
            const closeBtn = createSafeElement('button', '✕');
            closeBtn.style.cssText = 'background: none; border: none; font-size: 1.5rem; cursor: pointer; color: #666;';
            closeBtn.onclick = () => hidePermissionDetailModal();
            
            headerDiv.appendChild(titleH3);
            headerDiv.appendChild(closeBtn);
            modalContent.appendChild(headerDiv);
            
            // 创建信息区域
            const infoDiv = createSafeElement('div');
            infoDiv.style.cssText = 'background: #f8f9fa; padding: 20px; border-radius: 12px; margin-bottom: 25px;';
            
            // 角色和范围信息
            const gridDiv = createSafeElement('div');
            gridDiv.style.cssText = 'display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin-bottom: 15px;';
            
            // 当前角色
            const roleInfoDiv = createSafeElement('div');
            const roleLabel = createSafeElement('div', '👤 当前角色');
            roleLabel.style.cssText = 'font-size: 0.9rem; color: #666; margin-bottom: 5px;';
            const roleValue = createSafeElement('div', escapeHtml(roleDisplay));
            roleValue.style.cssText = 'font-size: 1.1rem; font-weight: 600; color: #333;';
            roleInfoDiv.appendChild(roleLabel);
            roleInfoDiv.appendChild(roleValue);
            
            // 目标范围
            const scopeInfoDiv = createSafeElement('div');
            const scopeLabel = createSafeElement('div', '🎯 目标范围');
            scopeLabel.style.cssText = 'font-size: 0.9rem; color: #666; margin-bottom: 5px;';
            const scopeValue = createSafeElement('div', escapeHtml(scopeTitle));
            scopeValue.style.cssText = 'font-size: 1.1rem; font-weight: 600; color: #333;';
            scopeInfoDiv.appendChild(scopeLabel);
            scopeInfoDiv.appendChild(scopeValue);
            
            gridDiv.appendChild(roleInfoDiv);
            gridDiv.appendChild(scopeInfoDiv);
            
            // 权限统计
            const statsDiv = createSafeElement('div');
            statsDiv.style.cssText = 'display: grid; grid-template-columns: 1fr 1fr; gap: 20px;';
            
            const permissionStatsDiv = createSafeElement('div');
            const statsLabel = createSafeElement('div', '📊 权限统计');
            statsLabel.style.cssText = 'font-size: 0.9rem; color: #666; margin-bottom: 5px;';
            const statsValue = createSafeElement('div', `${allowedLevels.length}/${totalLevels} 级别可用`);
            statsValue.style.cssText = `font-size: 1.1rem; font-weight: 600; color: ${hasPermission ? '#28a745' : '#dc3545'};`;
            permissionStatsDiv.appendChild(statsLabel);
            permissionStatsDiv.appendChild(statsValue);
            
            const statusDiv = createSafeElement('div');
            const statusLabel = createSafeElement('div', '🎯 权限状态');
            statusLabel.style.cssText = 'font-size: 0.9rem; color: #666; margin-bottom: 5px;';
            const statusValue = createSafeElement('div', hasPermission ? '✅ 有权限' : '❌ 无权限');
            statusValue.style.cssText = `font-size: 1.1rem; font-weight: 600; color: ${hasPermission ? '#28a745' : '#dc3545'};`;
            statusDiv.appendChild(statusLabel);
            statusDiv.appendChild(statusValue);
            
            statsDiv.appendChild(permissionStatsDiv);
            statsDiv.appendChild(statusDiv);
            
            infoDiv.appendChild(gridDiv);
            infoDiv.appendChild(statsDiv);
            modalContent.appendChild(infoDiv);
            
            // 级别详情
            const levelsDiv = createSafeElement('div');
            levelsDiv.style.marginBottom = '25px';
            const levelsTitle = createSafeElement('h4', '📋 各级别权限详情');
            levelsTitle.style.cssText = 'margin-bottom: 15px; color: #333; display: flex; align-items: center; gap: 8px;';
            levelsDiv.appendChild(levelsTitle);
            
            // 生成级别详情项
            for (let level = 1; level <= 4; level++) {
                const levelInfo = NOTIFICATION_LEVELS[level];
                const hasThisLevel = allowedLevels.includes(level);
                const statusClass = hasThisLevel ? 'level-detail-allowed' : 'level-detail-denied';
                const statusIcon = hasThisLevel ? '✅' : '❌';
                const statusText = hasThisLevel ? '允许发布' : '无权发布';
                
                const levelItemDiv = createSafeElement('div', '', `level-detail-item ${statusClass}`);
                
                const leftDiv = createSafeElement('div');
                leftDiv.style.cssText = 'display: flex; align-items: center; gap: 10px;';
                
                const iconSpan = createSafeElement('span', levelInfo.icon);
                iconSpan.style.fontSize = '1.2rem';
                
                const infoDiv2 = createSafeElement('div');
                const nameDiv = createSafeElement('div', `${level}级 - ${levelInfo.name}`);
                nameDiv.style.cssText = `font-weight: 600; color: ${levelInfo.color};`;
                const descDiv = createSafeElement('div', escapeHtml(levelInfo.description));
                descDiv.style.cssText = 'font-size: 0.9rem; opacity: 0.8;';
                
                infoDiv2.appendChild(nameDiv);
                infoDiv2.appendChild(descDiv);
                leftDiv.appendChild(iconSpan);
                leftDiv.appendChild(infoDiv2);
                
                const rightDiv = createSafeElement('div');
                rightDiv.style.cssText = 'display: flex; align-items: center; gap: 8px; font-weight: 600;';
                rightDiv.appendChild(createSafeElement('span', statusIcon));
                rightDiv.appendChild(createSafeElement('span', statusText));
                
                levelItemDiv.appendChild(leftDiv);
                levelItemDiv.appendChild(rightDiv);
                levelsDiv.appendChild(levelItemDiv);
            }
            
            modalContent.appendChild(levelsDiv);
            
            // 结果区域
            const resultDiv = createSafeElement('div');
            resultDiv.style.cssText = `background: ${hasPermission ? '#d4edda' : '#f8d7da'}; padding: 20px; border-radius: 12px; margin-bottom: 20px;`;
            
            const resultTitle = createSafeElement('div', hasPermission ? '🎉 权限分析结果' : '⚠️ 权限限制说明');
            resultTitle.style.cssText = `color: ${hasPermission ? '#155724' : '#721c24'}; font-weight: 600; margin-bottom: 10px;`;
            
            const resultText = createSafeElement('div');
            resultText.style.cssText = `color: ${hasPermission ? '#155724' : '#721c24'}; line-height: 1.5;`;
            resultText.textContent = hasPermission ? 
                `${roleDisplay}拥有在${scopeTitle}发布${allowedLevels.length}个级别通知的权限。可以发布的级别包括：${allowedLevels.map(l => NOTIFICATION_LEVELS[l].name).join('、')}。` :
                `${roleDisplay}不具备${scopeTitle}的任何级别通知发布权限。如需发布相关通知，请通过有权限的上级角色或申请权限升级。`;
            
            resultDiv.appendChild(resultTitle);
            resultDiv.appendChild(resultText);
            modalContent.appendChild(resultDiv);
            
            // 确认按钮
            const buttonDiv = createSafeElement('div');
            buttonDiv.style.textAlign = 'center';
            const confirmBtn = createSafeElement('button', '确定', 'btn btn-primary');
            confirmBtn.onclick = () => hidePermissionDetailModal();
            buttonDiv.appendChild(confirmBtn);
            modalContent.appendChild(buttonDiv);
            
            modal.appendChild(modalContent);

            // 显示模态框
            setTimeout(() => {
                modal.classList.add('show');
            }, 10);
        }

        // 隐藏权限详情模态框（新增）
        function hidePermissionDetailModal() {
            const modal = document.getElementById('permissionDetailModal');
            if (modal) {
                modal.classList.remove('show');
                setTimeout(() => {
                    modal.remove();
                }, 300);
            }
        }

        // 页面内认证函数 - 增强版本，支持完整的双重认证流程
        async function authenticateInPage() {
            const selectedRole = document.getElementById('roleSelect').value;
            const authBtn = document.getElementById('authenticateBtn');
            const authStatus = document.getElementById('authStatus');
            
            try {
                authBtn.disabled = true;
                // 安全的按钮状态更新，避免XSS
                authBtn.textContent = '🔄 认证中...';
                authStatus.textContent = '正在认证...';
                authStatus.style.background = '#fff3cd';
                authStatus.style.color = '#856404';
                
                addLog('🚀 开始范围权限双重认证流程', 'info');
                addLog(`👤 选择角色: ${selectedRole} (${roleAccounts[selectedRole]?.displayName})`, 'info');
                
                const account = roleAccounts[selectedRole];
                if (!account) {
                    throw new Error('未找到对应角色的测试账号配置');
                }
                
                addLog(`🔑 使用测试账号: ${account.displayName}`, 'info');
                addLog(`🏢 员工编号: ${account.employeeId}`, 'info');
                addLog(`👤 用户姓名: ${account.name}`, 'info');
                
                // 显示加载状态
                showLoadingState('正在执行双重认证...');
                
                // 第一步：调用Mock School API进行身份认证
                addLog('🔐 第一步：Mock School API身份认证', 'info');
                
                const authResponse = await fetch(`${MOCK_API_BASE}/mock-school-api/auth/authenticate`, {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify({
                        employeeId: account.employeeId,
                        name: account.name,
                        password: account.password
                    })
                });
                
                addLog(`📤 认证API请求: POST ${MOCK_API_BASE}/mock-school-api/auth/authenticate`, 'info');
                addLog(`📥 认证API响应状态: ${authResponse.status} ${authResponse.statusText}`, 'info');
                
                if (!authResponse.ok) {
                    const errorText = await authResponse.text();
                    throw new Error(`Mock School API认证失败: HTTP ${authResponse.status} - ${errorText}`);
                }
                
                const authResult = await authResponse.json();
                addLog(`📥 认证API响应数据: ${JSON.stringify(authResult, null, 2)}`, 'info');
                
                if (!authResult.success || !authResult.data) {
                    throw new Error(authResult.message || 'Mock School API认证失败');
                }
                
                // 第二步：验证JWT Token并获取用户信息
                currentUser = authResult.data;
                currentToken = authResult.data.accessToken;
                
                if (!currentToken) {
                    throw new Error('认证成功但未获取到访问令牌');
                }
                
                addLog('✅ 第一步认证完成：获得JWT访问令牌', 'success');
                addLog(`🎟️ Token类型: ${typeof currentToken}`, 'info');
                addLog(`👤 用户信息: ${currentUser.realName || currentUser.username} (${currentUser.roleCode})`, 'info');
                
                // 第三步：验证Token有效性（可选）
                addLog('🔍 第二步：验证Token有效性', 'info');
                const cleanToken = currentToken.startsWith('Bearer ') ? currentToken.substring(7) : currentToken;
                
                const tokenVerifyResponse = await fetch(`${MOCK_API_BASE}/mock-school-api/auth/verify`, {
                    method: 'POST',
                    headers: {
                        'Authorization': `Bearer ${cleanToken}`,
                        'Content-Type': 'application/json'
                    }
                });
                
                if (tokenVerifyResponse.ok) {
                    const verifyResult = await tokenVerifyResponse.json();
                    addLog('✅ Token验证通过', 'success');
                    addLog(`🎯 Token状态: ${verifyResult.data?.valid ? '有效' : '无效'}`, 'info');
                } else {
                    addLog('⚠️ Token验证接口调用失败，但继续执行', 'warning');
                }
                
                // 隐藏加载状态
                hideLoadingState();
                
                addLog(`🎉 双重认证流程完成！用户: ${currentUser.realName || currentUser.username}`, 'success');
                addLog(`🏆 角色权限: ${roleAccounts[currentUser.roleCode]?.displayName}`, 'success');
                
                // 更新UI状态
                updateAuthStatus();
                showMainContent();
                
                // 立即初始化范围权限功能
                await initializeScopePermissions();
                
            } catch (error) {
                // 隐藏加载状态
                hideLoadingState();
                
                addLog(`❌ 双重认证失败: ${error.message}`, 'error');
                
                // 分析错误类型并提供相应建议
                let errorAdvice = '';
                if (error.message.includes('Failed to fetch') || error.message.includes('NetworkError')) {
                    errorAdvice = '\n\n建议检查事项：\n• 确认Mock School API服务已启动（端口48082）\n• 检查网络连接是否正常\n• 确认防火墙未阻止连接';
                } else if (error.message.includes('401') || error.message.includes('Unauthorized')) {
                    errorAdvice = '\n\n建议检查事项：\n• 确认账号密码是否正确\n• 检查用户角色权限配置\n• 确认服务端认证逻辑';
                } else if (error.message.includes('500')) {
                    errorAdvice = '\n\n建议检查事项：\n• 查看服务器端错误日志\n• 确认数据库连接正常\n• 检查服务端配置';
                }
                
                authStatus.textContent = `❌ 认证失败: ${error.message}`;
                authStatus.style.background = '#f8d7da';
                authStatus.style.color = '#721c24';
                
                // 显示详细错误信息
                showErrorAlert(`双重认证失败：\n\n${error.message}${errorAdvice}`);
                
            } finally {
                authBtn.disabled = false;
                authBtn.textContent = '🚀 一键认证';
            }
        }

        // 更新认证状态显示
        function updateAuthStatus() {
            const authStatus = document.getElementById('authStatus');
            const authTitle = document.getElementById('authTitle');
            
            if (!authStatus || !authTitle) {
                addLog('❌ 认证状态显示元素不存在', 'error');
                return;
            }
            
            if (currentUser) {
                const displayName = currentUser.realName || currentUser.username || '未知用户';
                const roleTitle = roleAccounts[currentUser.roleCode]?.displayName || currentUser.roleCode;
                const roleIcon = getRoleIcon(currentUser.roleCode);
                
                try {
                    authStatus.textContent = `✅ 已认证：${displayName} (${roleTitle})`;
                    authStatus.style.background = '#d4edda';
                    authStatus.style.color = '#155724';
                    
                    authTitle.textContent = `🔑 已认证：${roleIcon} ${displayName} - ${roleTitle}视角`;
                    
                    // 折叠认证区域
                    setTimeout(() => {
                        const authSection = document.getElementById('authSection');
                        const toggleBtn = document.getElementById('toggleAuthBtn');
                        
                        if (authSection) {
                            authSection.classList.add('hidden');
                        }
                        if (toggleBtn) {
                            toggleBtn.style.display = 'inline-block';
                        }
                    }, 2000);
                    
                } catch (error) {
                    addLog(`❌ 更新认证状态显示失败: ${error.message}`, 'error');
                }
            }
        }

        // 显示主内容区域
        function showMainContent() {
            const mainContent = document.getElementById('mainContent');
            
            if (!mainContent) {
                addLog('❌ 主内容区域不存在', 'error');
                return;
            }
            
            try {
                mainContent.classList.remove('d-none');
                
                updateUserInfoPanel();
                updateScopePermissionPanel();
                refreshAvailableScopes();
                
                addLog('✅ 主内容区域已显示', 'success');
            } catch (error) {
                addLog(`❌ 显示主内容区域失败: ${error.message}`, 'error');
            }
        }

        // 初始化范围权限功能 - 增强版本，支持自动API调用
        async function initializeScopePermissions() {
            addLog('🎯 初始化范围权限控制功能', 'info');
            
            if (!currentUser) {
                addLog('❌ 用户未认证，无法初始化范围权限', 'error');
                return;
            }
            
            try {
                // 显示范围选择器
                const scopeSelectorSection = document.getElementById('scopeSelectorSection');
                if (scopeSelectorSection) {
                    scopeSelectorSection.style.display = 'block';
                    addLog('✅ 范围选择器已显示', 'success');
                }
                
                // 高亮当前用户在权限矩阵中的行
                highlightCurrentUserInMatrix();
                
                // 自动调用API获取可用范围
                addLog('🚀 自动获取用户可用范围...', 'info');
                await refreshAvailableScopes();
                
                // 如果获取到范围，在单选模式下自动选择第一个可用范围进行演示
                if (currentAvailableScopes.length > 0) {
                    const firstAvailableScope = currentAvailableScopes[0];
                    if (scopeSelectionMode === 'single' && firstAvailableScope && scopeConfig[firstAvailableScope]) {
                        addLog(`🎯 自动选择第一个可用范围进行演示: ${scopeConfig[firstAvailableScope].title}`, 'info');
                        currentSelectedScopes = [firstAvailableScope];
                        renderScopeOptions(); // 重新渲染以显示选择状态
                    } else if (!scopeConfig[firstAvailableScope]) {
                        addLog(`⚠️ 第一个可用范围配置不存在: ${firstAvailableScope}`, 'warning');
                    }
                }
                
                addLog('✅ 范围权限功能初始化完成', 'success');
                addLog(`📊 最终状态: 用户${currentUser.realName}拥有${currentAvailableScopes.length}个可用范围`, 'success');
                
            } catch (error) {
                addLog(`❌ 初始化范围权限功能失败: ${error.message}`, 'error');
            }
        }

        // 高亮权限矩阵中当前用户的行
        function highlightCurrentUserInMatrix() {
            if (!currentUser) return;
            
            try {
                // 移除之前的高亮
                const prevHighlighted = document.querySelectorAll('.matrix-table tr.current-user');
                prevHighlighted.forEach(row => row.classList.remove('current-user'));
                
                // 高亮当前用户的行
                const matrixRows = document.querySelectorAll('.matrix-table tbody tr');
                matrixRows.forEach(row => {
                    const firstCell = row.querySelector('td');
                    if (firstCell && firstCell.textContent.includes(roleAccounts[currentUser.roleCode]?.displayName)) {
                        row.style.background = 'linear-gradient(135deg, #fff3cd 0%, #ffeaa7 100%)';
                        row.style.borderLeft = '4px solid #ffc107';
                        row.classList.add('current-user');
                    }
                });
                
                addLog(`✅ 已高亮当前用户权限行: ${currentUser.roleCode}`, 'info');
                
            } catch (error) {
                addLog(`❌ 高亮权限矩阵失败: ${error.message}`, 'error');
            }
        }

        // 刷新可用范围 - 增强版本，支持真实API集成
        async function refreshAvailableScopes() {
            if (!currentUser || !currentToken) {
                addLog('❌ 用户未认证，无法获取可用范围', 'error');
                return;
            }
            
            try {
                addLog('🔄 获取用户可用范围选项...', 'info');
                addLog(`👤 当前用户: ${currentUser.realName} (${currentUser.roleCode})`, 'info');
                
                const cleanToken = currentToken.startsWith('Bearer ') ? currentToken.substring(7) : currentToken;
                
                // 显示加载状态
                showLoadingState('正在获取可用范围...');
                
                const response = await fetch(`${API_BASE}/admin-api/test/notification/api/available-scopes`, {
                    method: 'GET',
                    headers: {
                        'Authorization': `Bearer ${cleanToken}`,
                        'tenant-id': '1',
                        'Content-Type': 'application/json'
                    }
                });
                
                addLog(`📤 API请求: GET /admin-api/test/notification/api/available-scopes`, 'info');
                addLog(`📤 请求头: Authorization: Bearer *****, tenant-id: 1`, 'info');
                addLog(`📥 API响应状态: ${response.status} ${response.statusText}`, 'info');
                
                // 隐藏加载状态
                hideLoadingState();
                
                if (response.ok) {
                    const result = await response.json();
                    addLog(`📥 API响应数据: ${JSON.stringify(result, null, 2)}`, 'info');
                    
                    if (result.code === 0 && result.data) {
                        // 处理成功响应
                        const apiScopes = result.data.availableScopes || [];
                        const userRole = result.data.roleCode || currentUser.roleCode;
                        const rolePermissions = result.data.rolePermissions || {};
                        
                        // 修复：API返回的是对象数组，需要提取code属性
                        if (Array.isArray(apiScopes) && apiScopes.length > 0 && typeof apiScopes[0] === 'object') {
                            currentAvailableScopes = apiScopes.map(scope => scope.code);
                            addLog(`🔧 已转换API对象数组为范围代码数组: [${currentAvailableScopes.join(', ')}]`, 'info');
                        } else {
                            currentAvailableScopes = apiScopes;
                        }
                        
                        addLog(`✅ API返回成功: 角色=${userRole}, 可用范围=${currentAvailableScopes.length}个`, 'success');
                        addLog(`🎯 可用范围列表: [${currentAvailableScopes.join(', ')}]`, 'success');
                        
                        // 验证API结果与本地配置的一致性
                        const localRolePermissions = ENHANCED_PERMISSION_MATRIX[currentUser.roleCode] || {};
                        const localScopes = Object.keys(localRolePermissions).filter(scope => {
                            return localRolePermissions[scope] && localRolePermissions[scope].length > 0;
                        });
                        const isConsistent = JSON.stringify([...apiScopes].sort()) === JSON.stringify([...localScopes].sort());
                        
                        if (isConsistent) {
                            addLog('✅ API结果与本地权限配置完全一致', 'success');
                        } else {
                            addLog('⚠️ API结果与本地配置存在差异，以API结果为准', 'warning');
                            addLog(`🔍 本地配置: [${localScopes.join(', ')}]`, 'info');
                            addLog(`🔍 API配置: [${apiScopes.join(', ')}]`, 'info');
                        }
                        
                        renderScopeOptions();
                        updateScopePermissionPanel();
                        updateMatrixWithAPIData(result.data);
                        
                    } else {
                        throw new Error(result.msg || result.message || '获取范围选项失败');
                    }
                } else {
                    // 处理HTTP错误状态
                    let errorMessage = `HTTP ${response.status}: ${response.statusText}`;
                    
                    try {
                        const errorData = await response.json();
                        errorMessage = errorData.msg || errorData.message || errorMessage;
                        addLog(`📥 错误详情: ${JSON.stringify(errorData)}`, 'error');
                    } catch (parseError) {
                        addLog('❌ 无法解析错误响应', 'warning');
                    }
                    
                    throw new Error(errorMessage);
                }
                
            } catch (error) {
                // 隐藏加载状态
                hideLoadingState();
                
                addLog(`❌ 获取可用范围失败: ${error.message}`, 'error');
                
                // 分析错误类型并提供相应处理
                if (error.message.includes('Failed to fetch') || error.message.includes('NetworkError')) {
                    addLog('🌐 网络连接问题：请检查服务器是否启动', 'warning');
                    addLog('💡 建议：请确认48081端口服务正常运行', 'info');
                } else if (error.message.includes('401') || error.message.includes('Unauthorized')) {
                    addLog('🔐 认证问题：Token可能已过期，请重新登录', 'warning');
                } else if (error.message.includes('403') || error.message.includes('Forbidden')) {
                    addLog('🚫 权限问题：当前用户没有访问该接口的权限', 'warning');
                } else if (error.message.includes('500')) {
                    addLog('🔧 服务器内部错误：请检查服务器日志', 'warning');
                }
                
                // 使用本地配置作为备选方案
                addLog('🔄 切换到本地权限配置作为备选方案', 'info');
                
                // 从增强权限矩阵中获取该角色的可用范围
                const rolePermissions = ENHANCED_PERMISSION_MATRIX[currentUser.roleCode] || {};
                currentAvailableScopes = Object.keys(rolePermissions).filter(scope => {
                    return rolePermissions[scope] && rolePermissions[scope].length > 0;
                });
                
                addLog(`📋 本地配置提供${currentAvailableScopes.length}个可用范围: [${currentAvailableScopes.join(', ')}]`, 'info');
                
                renderScopeOptions();
                updateScopePermissionPanel();
                
                // 显示错误提示
                showErrorAlert(`API调用失败：${error.message}\n\n已切换到本地权限配置，功能仍可正常使用。`);
            }
        }

        // 渲染范围选项 - 增强版本，支持单选/多选和详细权限信息
        function renderScopeOptions() {
            const container = document.getElementById('scopeOptions');
            const countElement = document.getElementById('availableScopeCount');
            
            if (!container) {
                addLog('❌ 范围选项容器不存在', 'error');
                return;
            }
            
            try {
                if (countElement) {
                    countElement.textContent = `(${currentAvailableScopes.length}个可用)`;
                }
                
                if (currentAvailableScopes.length === 0) {
                    // 安全的空状态显示，避免XSS
                    container.innerHTML = '';
                    const emptyDiv = createSafeElement('div');
                    emptyDiv.style.cssText = 'grid-column: 1/-1; text-align: center; padding: 40px; color: #666;';
                    
                    const iconDiv = createSafeElement('div', '📭');
                    iconDiv.style.cssText = 'font-size: 2rem; margin-bottom: 15px;';
                    const titleDiv = createSafeElement('div', '暂无可用范围');
                    titleDiv.style.cssText = 'font-size: 1.2rem; margin-bottom: 10px;';
                    const descDiv = createSafeElement('div', '当前角色没有任何通知发布范围权限');
                    descDiv.style.cssText = 'font-size: 0.9rem; opacity: 0.7;';
                    
                    emptyDiv.appendChild(iconDiv);
                    emptyDiv.appendChild(titleDiv);
                    emptyDiv.appendChild(descDiv);
                    container.appendChild(emptyDiv);
                    
                    updateScopeSelectionSummary();
                    return;
                }
                
                // 安全的范围选项渲染，避免XSS
                container.innerHTML = ''; // 清空现有内容
                const allScopes = ['SCHOOL_WIDE', 'DEPARTMENT', 'CLASS', 'GRADE'];
                
                allScopes.forEach(scope => {
                    const config = scopeConfig[scope];
                    const isAvailable = currentAvailableScopes.includes(scope);
                    const isSelected = currentSelectedScopes.includes(scope);
                    
                    // 获取该角色在这个范围的权限级别详情
                    const allowedLevels = ENHANCED_PERMISSION_MATRIX[currentUser?.roleCode]?.[scope] || [];
                    const levelCount = allowedLevels.length;
                    
                    // 创建范围选项元素
                    const optionDiv = createSafeElement('div', '', `scope-option ${isSelected ? 'selected' : ''} ${!isAvailable ? 'disabled' : ''}`);
                    optionDiv.setAttribute('data-scope', scope);
                    optionDiv.title = `${config.title}: ${isAvailable ? `${levelCount}个权限级别` : '无权限'}`;
                    
                    if (isAvailable) {
                        optionDiv.onclick = () => toggleScopeSelection(scope);
                    } else {
                        optionDiv.onclick = () => showScopeDisabledReason(scope);
                    }
                    
                    // 图标
                    const iconDiv = createSafeElement('div', config.icon, 'scope-icon');
                    optionDiv.appendChild(iconDiv);
                    
                    // 标题
                    const titleDiv = createSafeElement('div', config.title, 'scope-title');
                    optionDiv.appendChild(titleDiv);
                    
                    // 描述
                    const descDiv = createSafeElement('div', config.description, 'scope-description');
                    optionDiv.appendChild(descDiv);
                    
                    // 权限徽章
                    const badgeDiv = createSafeElement('div', '', `scope-permission-badge ${isAvailable ? 'available' : 'unavailable'}`);
                    const badgeIcon = createSafeElement('span', isAvailable ? '✅' : '❌');
                    const badgeText = createSafeElement('span', isAvailable ? `${levelCount}级权限` : '无权限');
                    badgeDiv.appendChild(badgeIcon);
                    badgeDiv.appendChild(badgeText);
                    optionDiv.appendChild(badgeDiv);
                    
                    // 权限级别详情
                    if (isAvailable && levelCount > 0) {
                        const levelNames = allowedLevels.map(l => NOTIFICATION_LEVELS[l].name).join('、');
                        const levelDiv = createSafeElement('div', `可发布: ${levelNames}`, 'scope-permission-level');
                        optionDiv.appendChild(levelDiv);
                    }
                    
                    // 选中标记
                    if (isSelected) {
                        const checkDiv = createSafeElement('div', '✓');
                        checkDiv.style.cssText = 'position: absolute; top: 10px; right: 10px; background: #28a745; color: white; width: 20px; height: 20px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 0.8rem;';
                        optionDiv.appendChild(checkDiv);
                    }
                    
                    container.appendChild(optionDiv);
                });
                updateScopeSelectionSummary();
                updateScopePermissionDetails();
                
                addLog(`🎨 已渲染 ${allScopes.length} 个范围选项 (${currentAvailableScopes.length}个可用, ${currentSelectedScopes.length}个已选)`, 'success');
                
            } catch (error) {
                addLog(`❌ 渲染范围选项失败: ${error.message}`, 'error');
            }
        }

        // 设置范围选择模式
        function setScopeSelectionMode(mode) {
            scopeSelectionMode = mode;
            
            // 更新模式按钮状态
            document.querySelectorAll('.scope-mode-btn').forEach(btn => {
                btn.classList.remove('active');
            });
            
            if (mode === 'single') {
                document.getElementById('singleModeBtn').classList.add('active');
                // 在单选模式下，只保留第一个选择
                if (currentSelectedScopes.length > 1) {
                    currentSelectedScopes = currentSelectedScopes.slice(0, 1);
                }
            } else {
                document.getElementById('multiModeBtn').classList.add('active');
            }
            
            addLog(`🔧 切换到${mode === 'single' ? '单选' : '多选'}模式`, 'info');
            renderScopeOptions();
        }

        // 切换范围选择状态（支持单选/多选）
        function toggleScopeSelection(scope) {
            if (!currentAvailableScopes.includes(scope)) {
                addLog(`⚠️ 尝试选择无权限的范围: ${scope}`, 'warning');
                showScopeDisabledReason(scope);
                return;
            }
            
            try {
                const isCurrentlySelected = currentSelectedScopes.includes(scope);
                
                if (scopeSelectionMode === 'single') {
                    // 单选模式：清空其他选择，切换当前选择
                    if (isCurrentlySelected) {
                        currentSelectedScopes = [];
                    } else {
                        currentSelectedScopes = [scope];
                    }
                } else {
                    // 多选模式：切换当前选择
                    if (isCurrentlySelected) {
                        currentSelectedScopes = currentSelectedScopes.filter(s => s !== scope);
                    } else {
                        currentSelectedScopes.push(scope);
                    }
                }
                
                const config = scopeConfig[scope];
                const action = currentSelectedScopes.includes(scope) ? '选中' : '取消选中';
                addLog(`🎯 ${action}范围: ${config.title} (${scope})`, 'success');
                
                // 更新UI显示
                renderScopeOptions();
                updateTestButtonState();
                
            } catch (error) {
                addLog(`❌ 切换范围选择状态失败: ${error.message}`, 'error');
            }
        }

        // 更新选择摘要显示
        function updateScopeSelectionSummary() {
            const summaryDiv = document.getElementById('scopeSelectionSummary');
            const countElement = document.getElementById('selectionCount');
            const detailsElement = document.getElementById('selectionDetails');
            
            if (!summaryDiv || !countElement || !detailsElement) {
                return;
            }
            
            try {
                const selectedCount = currentSelectedScopes.length;
                
                if (selectedCount === 0) {
                    summaryDiv.style.display = 'none';
                } else {
                    summaryDiv.style.display = 'block';
                    countElement.textContent = selectedCount;
                    
                    // 构建选择详情
                    const selectedDetails = currentSelectedScopes.map(scope => {
                        const config = scopeConfig[scope];
                        if (!config) {
                            addLog(`⚠️ 范围配置不存在: ${scope}`, 'warning');
                            return `⚠️ ${scope} (配置缺失)`;
                        }
                        const levels = ENHANCED_PERMISSION_MATRIX[currentUser?.roleCode]?.[scope] || [];
                        return `${config.icon} ${config.title} (${levels.length}级)`;
                    }).join(' • ');
                    
                    detailsElement.textContent = selectedDetails;
                }
                
            } catch (error) {
                addLog(`❌ 更新选择摘要失败: ${error.message}`, 'error');
            }
        }

        // 更新权限详情显示 - 安全版本，避免XSS
        function updateScopePermissionDetails() {
            const detailsDiv = document.getElementById('scopePermissionDetails');
            const contentDiv = document.getElementById('permissionDetailsContent');
            
            if (!detailsDiv || !contentDiv) {
                return;
            }
            
            try {
                if (currentSelectedScopes.length === 0) {
                    detailsDiv.style.display = 'none';
                    return;
                }
                
                detailsDiv.style.display = 'block';
                
                // 安全的内容构建，避免XSS
                contentDiv.innerHTML = ''; // 清空现有内容
                
                currentSelectedScopes.forEach(scope => {
                    const config = scopeConfig[scope];
                    if (!config) {
                        addLog(`⚠️ 权限详情：范围配置不存在: ${scope}`, 'warning');
                        return; // 跳过这个无效的范围
                    }
                    const levels = ENHANCED_PERMISSION_MATRIX[currentUser?.roleCode]?.[scope] || [];
                    
                    // 创建范围详情容器
                    const scopeDiv = createSafeElement('div');
                    scopeDiv.style.cssText = `margin-bottom: 20px; padding: 15px; background: white; border-radius: 10px; border-left: 4px solid ${config.color};`;
                    
                    // 创建头部信息
                    const headerDiv = createSafeElement('div');
                    headerDiv.style.cssText = 'display: flex; align-items: center; gap: 10px; margin-bottom: 10px;';
                    
                    const iconSpan = createSafeElement('span', config.icon);
                    iconSpan.style.fontSize = '1.2rem';
                    
                    const infoDiv = createSafeElement('div');
                    const titleDiv = createSafeElement('div', config.title);
                    titleDiv.style.cssText = 'font-weight: 600; color: #333;';
                    const descDiv = createSafeElement('div', config.description);
                    descDiv.style.cssText = 'font-size: 0.9rem; opacity: 0.8;';
                    
                    infoDiv.appendChild(titleDiv);
                    infoDiv.appendChild(descDiv);
                    headerDiv.appendChild(iconSpan);
                    headerDiv.appendChild(infoDiv);
                    
                    // 创建权限级别信息
                    const levelDiv = createSafeElement('div');
                    levelDiv.style.fontSize = '0.9rem';
                    
                    const levelLabel = createSafeElement('strong', '可发布权限级别：');
                    levelDiv.appendChild(levelLabel);
                    
                    levels.forEach(level => {
                        const levelInfo = NOTIFICATION_LEVELS[level];
                        const levelSpan = createSafeElement('span', `${levelInfo.icon} ${levelInfo.name}`);
                        levelSpan.style.cssText = `display: inline-block; margin: 2px 5px 2px 0; padding: 2px 8px; background: ${levelInfo.color}22; color: ${levelInfo.color}; border-radius: 12px; font-size: 0.8rem;`;
                        levelDiv.appendChild(levelSpan);
                    });
                    
                    scopeDiv.appendChild(headerDiv);
                    scopeDiv.appendChild(levelDiv);
                    contentDiv.appendChild(scopeDiv);
                });
                
            } catch (error) {
                addLog(`❌ 更新权限详情失败: ${error.message}`, 'error');
            }
        }

        // 更新测试按钮状态 - 安全版本，避免XSS
        function updateTestButtonState() {
            const testButton = document.getElementById('testScopePermission');
            if (testButton) {
                testButton.disabled = currentSelectedScopes.length === 0;
                
                if (currentSelectedScopes.length === 0) {
                    testButton.textContent = '🧪 测试选中权限';
                } else if (currentSelectedScopes.length === 1) {
                    testButton.textContent = '🧪 测试选中权限';
                } else {
                    testButton.textContent = `🧪 测试${currentSelectedScopes.length}个权限`;
                }
            }
        }

        // 测试选中的范围权限（支持多个范围）
        async function testSelectedScopePermissions() {
            if (currentSelectedScopes.length === 0) {
                showErrorAlert('请先选择要测试的范围');
                return;
            }
            
            if (!currentUser || !currentToken) {
                addLog('❌ 用户未认证，无法测试权限', 'error');
                showErrorAlert('用户未认证，请先登录');
                return;
            }
            
            try {
                const scopeTitles = currentSelectedScopes.map(s => scopeConfig[s]?.title).join('、');
                addLog(`🧪 开始测试选中的范围权限: ${scopeTitles}`, 'info');
                addLog(`👤 测试用户: ${currentUser.realName} (${currentUser.roleCode})`, 'info');
                addLog(`📊 测试范围数量: ${currentSelectedScopes.length}个`, 'info');
                
                // 显示加载状态
                showLoadingState(`正在测试 ${currentSelectedScopes.length} 个范围权限...`);
                
                const results = [];
                
                // 逐个测试选中的范围
                for (const scope of currentSelectedScopes) {
                    try {
                        const cleanToken = currentToken.startsWith('Bearer ') ? currentToken.substring(7) : currentToken;
                        
                        const testRequest = {
                            targetScope: scope,
                            testType: 'MULTI_SCOPE_PERMISSION_TEST',
                            roleCode: currentUser.roleCode,
                            userInfo: {
                                name: currentUser.realName || currentUser.username,
                                roleCode: currentUser.roleCode,
                                employeeId: currentUser.employeeId || currentUser.username
                            },
                            testMetadata: {
                                testTime: new Date().toISOString(),
                                selectedScopes: currentSelectedScopes,
                                selectionMode: scopeSelectionMode,
                                clientInfo: {
                                    userAgent: navigator.userAgent,
                                    timestamp: Date.now()
                                }
                            }
                        };
                        
                        const response = await fetch(`${API_BASE}/admin-api/test/notification/api/scope-test`, {
                            method: 'POST',
                            headers: {
                                'Authorization': `Bearer ${cleanToken}`,
                                'tenant-id': '1',
                                'Content-Type': 'application/json'
                            },
                            body: JSON.stringify(testRequest)
                        });
                        
                        if (response.ok) {
                            const result = await response.json();
                            if (result.code === 0 && result.data) {
                                const testData = result.data;
                                const isSuccess = testData.testResult === 'SUCCESS' || testData.success === true;
                                const hasPermission = testData.hasPermission !== false;
                                
                                results.push({
                                    scope: scope,
                                    scopeTitle: scopeConfig[scope].title,
                                    success: isSuccess,
                                    hasPermission: hasPermission,
                                    levels: ENHANCED_PERMISSION_MATRIX[currentUser.roleCode]?.[scope] || [],
                                    apiResult: true
                                });
                            } else {
                                throw new Error(result.msg || result.message || 'API返回错误');
                            }
                        } else {
                            throw new Error(`HTTP ${response.status}: ${response.statusText}`);
                        }
                        
                        // 添加延迟避免请求过快
                        await new Promise(resolve => setTimeout(resolve, 300));
                        
                    } catch (error) {
                        // 使用本地配置作为备用
                        const hasPermission = currentAvailableScopes.includes(scope);
                        results.push({
                            scope: scope,
                            scopeTitle: scopeConfig[scope].title,
                            success: hasPermission,
                            hasPermission: hasPermission,
                            levels: ENHANCED_PERMISSION_MATRIX[currentUser.roleCode]?.[scope] || [],
                            apiResult: false,
                            error: error.message
                        });
                        
                        addLog(`⚠️ 范围${scope}API测试失败，使用本地配置: ${error.message}`, 'warning');
                    }
                }
                
                // 隐藏加载状态
                hideLoadingState();
                
                // 显示综合测试结果
                showMultiScopeTestResults(results);
                
                const successCount = results.filter(r => r.hasPermission).length;
                addLog(`✅ 多范围权限测试完成: ${successCount}/${results.length} 通过`, 'success');
                
            } catch (error) {
                hideLoadingState();
                addLog(`❌ 多范围权限测试失败: ${error.message}`, 'error');
                showErrorAlert(`权限测试失败：${error.message}`);
            }
        }

        // 显示多范围测试结果 - 安全版本，避免XSS
        function showMultiScopeTestResults(results) {
            const container = document.getElementById('testResultsContent');
            const section = document.getElementById('testResultsSection');
            
            if (!container || !section) return;
            
            try {
                section.classList.remove('d-none');
                
                const successCount = results.filter(r => r.hasPermission).length;
                const totalCount = results.length;
                const allFromAPI = results.every(r => r.apiResult);
                
                // 安全的内容构建，避免XSS
                container.innerHTML = ''; // 清空现有内容
                
                // 基本信息
                const items = [
                    { label: '🎯 测试类型', value: `${scopeSelectionMode === 'single' ? '单范围' : '多范围'}权限测试`, strong: true },
                    { label: '📊 测试结果', value: `${successCount}/${totalCount} 通过`, strong: true },
                    { label: '👤 当前角色', value: roleAccounts[currentUser.roleCode]?.displayName, strong: true },
                    { label: '⏰ 测试时间', value: new Date().toLocaleString() },
                    { label: '📡 数据源', value: allFromAPI ? 'API响应' : 'API+本地配置', strong: true }
                ];
                
                items.forEach(item => {
                    const itemDiv = createSafeElement('div', '', 'test-result-item');
                    const labelSpan = createSafeElement('span', item.label);
                    const valueSpan = createSafeElement('span', item.value);
                    if (item.strong) {
                        const strongSpan = createSafeElement('strong', item.value);
                        valueSpan.innerHTML = '';
                        valueSpan.appendChild(strongSpan);
                    }
                    itemDiv.appendChild(labelSpan);
                    itemDiv.appendChild(valueSpan);
                    container.appendChild(itemDiv);
                });
                
                // 详细结果
                const detailDiv = createSafeElement('div');
                detailDiv.style.marginTop = '20px';
                
                const detailTitle = createSafeElement('h5', '📋 各范围详细结果：');
                detailDiv.appendChild(detailTitle);
                
                const resultGrid = createSafeElement('div');
                resultGrid.style.cssText = 'display: grid; gap: 10px;';
                
                results.forEach(result => {
                    const statusIcon = result.hasPermission ? '✅' : '❌';
                    const statusText = result.hasPermission ? '有权限' : '无权限';
                    const levelText = result.levels.length > 0 ? `(${result.levels.length}级)` : '';
                    
                    const resultItemDiv = createSafeElement('div');
                    resultItemDiv.style.cssText = `display: flex; justify-content: space-between; align-items: center; padding: 10px; background: ${result.hasPermission ? '#d4edda' : '#f8d7da'}; border-radius: 8px; color: ${result.hasPermission ? '#155724' : '#721c24'};`;
                    
                    const leftSpan = createSafeElement('span');
                    leftSpan.appendChild(createSafeElement('span', scopeConfig[result.scope].icon + ' '));
                    const titleStrong = createSafeElement('strong', result.scopeTitle);
                    leftSpan.appendChild(titleStrong);
                    leftSpan.appendChild(createSafeElement('span', ' ' + levelText));
                    
                    const rightSpan = createSafeElement('span', `${statusIcon} ${statusText}`);
                    rightSpan.style.fontWeight = '600';
                    
                    resultItemDiv.appendChild(leftSpan);
                    resultItemDiv.appendChild(rightSpan);
                    resultGrid.appendChild(resultItemDiv);
                });
                
                detailDiv.appendChild(resultGrid);
                container.appendChild(detailDiv);
                
                // 汇总说明
                let summaryDiv;
                if (successCount === totalCount) {
                    summaryDiv = createSafeElement('div');
                    summaryDiv.style.cssText = 'margin-top: 15px; padding: 15px; background: #d4edda; border-radius: 8px; color: #155724;';
                    const summaryTitle = createSafeElement('strong', '🎉 完美通过！');
                    const summaryText = createSafeElement('div', `您拥有所有${totalCount}个选中范围的通知发布权限。`);
                    summaryDiv.appendChild(summaryTitle);
                    summaryDiv.appendChild(document.createElement('br'));
                    summaryDiv.appendChild(summaryText);
                } else if (successCount > 0) {
                    summaryDiv = createSafeElement('div');
                    summaryDiv.style.cssText = 'margin-top: 15px; padding: 15px; background: #fff3cd; border-radius: 8px; color: #856404;';
                    const summaryTitle = createSafeElement('strong', '⚖️ 部分权限');
                    const summaryText = createSafeElement('div', `您拥有${successCount}个范围的权限，${totalCount - successCount}个范围无权限。这符合角色权限设计原则。`);
                    summaryDiv.appendChild(summaryTitle);
                    summaryDiv.appendChild(document.createElement('br'));
                    summaryDiv.appendChild(summaryText);
                } else {
                    summaryDiv = createSafeElement('div');
                    summaryDiv.style.cssText = 'margin-top: 15px; padding: 15px; background: #f8d7da; border-radius: 8px; color: #721c24;';
                    const summaryTitle = createSafeElement('strong', '❌ 全部无权限');
                    const summaryText = createSafeElement('div', '您没有任何选中范围的通知发布权限。请联系管理员检查角色配置。');
                    summaryDiv.appendChild(summaryTitle);
                    summaryDiv.appendChild(document.createElement('br'));
                    summaryDiv.appendChild(summaryText);
                }
                
                if (summaryDiv) {
                    container.appendChild(summaryDiv);
                }
                
                addLog('✅ 多范围测试结果已显示', 'success');
                
            } catch (error) {
                addLog(`❌ 显示多范围测试结果失败: ${error.message}`, 'error');
            }
        }

        // 清空所有选择
        function clearAllSelections() {
            currentSelectedScopes = [];
            renderScopeOptions();
            addLog('🗑️ 已清空所有范围选择', 'info');
        }

        // 全选可用范围
        function selectAllAvailable() {
            if (scopeSelectionMode === 'single' && currentAvailableScopes.length > 0) {
                currentSelectedScopes = [currentAvailableScopes[0]];
                addLog(`📍 单选模式：已选择第一个可用范围`, 'info');
            } else {
                currentSelectedScopes = [...currentAvailableScopes];
                addLog(`✅ 已选择所有${currentAvailableScopes.length}个可用范围`, 'info');
            }
            renderScopeOptions();
        }

        // 保持向后兼容的旧函数
        function selectScope(scope) {
            toggleScopeSelection(scope);
        }

        function testScopePermission() {
            testSelectedScopePermissions();
        }

        // 显示范围无权限原因
        function showScopeDisabledReason(scope) {
            const config = scopeConfig[scope];
            const userRole = roleAccounts[currentUser.roleCode]?.displayName || currentUser.roleCode;
            
            const reason = `
🚫 范围权限说明

🎯 范围：${config.title}
👤 当前角色：${userRole}
❌ 权限状态：无权限

📋 权限说明：
${userRole}不具备${config.title}的通知发布权限。

🎯 ${userRole}可用范围：
${currentAvailableScopes.map(s => `• ${scopeConfig[s].title}`).join('\n')}

💡 如需获得${config.title}权限：
• 联系系统管理员申请权限升级
• 或通过具有该权限的角色代为发布
• 或使用当前角色可用的其他范围

🔍 系统设计原理：
基于最小权限原则，每个角色只拥有执行其职责所必需的权限范围，
这样确保了通知系统的安全性和管理的规范性。
            `;
            
            alert(reason);
            addLog(`🚫 查看无权限范围说明: ${config.title}`, 'info');
        }

        // 测试范围权限 - 增强版本，支持完整的API集成
        async function testScopePermission() {
            if (!currentSelectedScope) {
                showErrorAlert('请先选择一个要测试的范围');
                return;
            }
            
            if (!currentUser || !currentToken) {
                addLog('❌ 用户未认证，无法测试权限', 'error');
                showErrorAlert('用户未认证，请先登录');
                return;
            }
            
            try {
                const scopeTitle = scopeConfig[currentSelectedScope]?.title || currentSelectedScope;
                addLog(`🧪 开始测试范围权限: ${scopeTitle} (${currentSelectedScope})`, 'info');
                addLog(`👤 测试用户: ${currentUser.realName} (${currentUser.roleCode})`, 'info');
                
                // 显示加载状态
                showLoadingState(`正在测试 ${scopeTitle} 权限...`);
                
                const cleanToken = currentToken.startsWith('Bearer ') ? currentToken.substring(7) : currentToken;
                
                // 构建详细测试请求
                const testRequest = {
                    targetScope: currentSelectedScope,
                    testType: 'SCOPE_PERMISSION_TEST',
                    roleCode: currentUser.roleCode,
                    userInfo: {
                        name: currentUser.realName || currentUser.username,
                        roleCode: currentUser.roleCode,
                        employeeId: currentUser.employeeId || currentUser.username
                    },
                    testMetadata: {
                        testTime: new Date().toISOString(),
                        clientInfo: {
                            userAgent: navigator.userAgent,
                            timestamp: Date.now()
                        },
                        expectedResult: currentAvailableScopes.includes(currentSelectedScope)
                    }
                };
                
                addLog(`📤 API请求: POST /admin-api/test/notification/api/scope-test`, 'info');
                addLog(`📤 请求数据: ${JSON.stringify(testRequest, null, 2)}`, 'info');
                
                const response = await fetch(`${API_BASE}/admin-api/test/notification/api/scope-test`, {
                    method: 'POST',
                    headers: {
                        'Authorization': `Bearer ${cleanToken}`,
                        'tenant-id': '1',
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify(testRequest)
                });
                
                // 隐藏加载状态
                hideLoadingState();
                
                addLog(`📥 测试API响应状态: ${response.status} ${response.statusText}`, 'info');
                
                if (response.ok) {
                    const result = await response.json();
                    addLog(`📥 测试API响应数据: ${JSON.stringify(result, null, 2)}`, 'info');
                    
                    if (result.code === 0 && result.data) {
                        const testData = result.data;
                        
                        // 分析测试结果
                        const isSuccess = testData.testResult === 'SUCCESS' || testData.success === true;
                        const hasPermission = testData.hasPermission !== false;
                        
                        addLog(`✅ 范围权限测试完成: ${isSuccess ? '成功' : '失败'}`, isSuccess ? 'success' : 'warning');
                        addLog(`🎯 权限状态: ${hasPermission ? '有权限' : '无权限'}`, hasPermission ? 'success' : 'warning');
                        
                        // 验证结果一致性
                        const expectedResult = currentAvailableScopes.includes(currentSelectedScope);
                        const isConsistent = hasPermission === expectedResult;
                        
                        if (isConsistent) {
                            addLog('✅ 测试结果与预期权限配置一致', 'success');
                        } else {
                            addLog('⚠️ 测试结果与预期权限配置不一致', 'warning');
                            addLog(`🔍 预期结果: ${expectedResult ? '有权限' : '无权限'}`, 'info');
                            addLog(`🔍 实际结果: ${hasPermission ? '有权限' : '无权限'}`, 'info');
                        }
                        
                        // 显示详细测试结果
                        showTestResults(testData);
                        
                    } else {
                        throw new Error(result.msg || result.message || '测试API返回无效数据');
                    }
                } else {
                    // 处理HTTP错误状态
                    let errorMessage = `HTTP ${response.status}: ${response.statusText}`;
                    
                    try {
                        const errorData = await response.json();
                        errorMessage = errorData.msg || errorData.message || errorMessage;
                        addLog(`📥 错误详情: ${JSON.stringify(errorData)}`, 'error');
                    } catch (parseError) {
                        addLog('❌ 无法解析错误响应', 'warning');
                    }
                    
                    throw new Error(errorMessage);
                }
                
            } catch (error) {
                // 隐藏加载状态
                hideLoadingState();
                
                addLog(`❌ 范围权限测试失败: ${error.message}`, 'error');
                
                // 分析错误类型
                if (error.message.includes('Failed to fetch') || error.message.includes('NetworkError')) {
                    addLog('🌐 网络连接问题：请检查服务器连接', 'warning');
                } else if (error.message.includes('401') || error.message.includes('Unauthorized')) {
                    addLog('🔐 认证问题：可能需要重新登录', 'warning');
                } else if (error.message.includes('403') || error.message.includes('Forbidden')) {
                    addLog('🚫 权限问题：没有执行该测试的权限', 'warning');
                } else if (error.message.includes('500')) {
                    addLog('🔧 服务器错误：请检查服务器状态', 'warning');
                }
                
                // 显示备用测试结果（基于本地配置）
                const localTestResult = {
                    testResult: currentAvailableScopes.includes(currentSelectedScope) ? 'SUCCESS' : 'FAILED',
                    hasPermission: currentAvailableScopes.includes(currentSelectedScope),
                    testScope: currentSelectedScope,
                    userRole: currentUser.roleCode,
                    errorMessage: `API调用失败: ${error.message}`,
                    fallbackMode: true,
                    localConfigResult: true
                };
                
                showTestResults(localTestResult);
                addLog('🔄 已显示基于本地配置的测试结果', 'info');
                
                // 显示错误提示
                showErrorAlert(`权限测试API调用失败：${error.message}\n\n已基于本地权限配置显示测试结果。`);
            }
        }

        // 显示测试结果 - 增强版本，支持API和本地配置结果
        function showTestResults(data) {
            const container = document.getElementById('testResultsContent');
            const section = document.getElementById('testResultsSection');
            
            if (!container || !section) {
                addLog('❌ 测试结果容器不存在', 'error');
                return;
            }
            
            try {
                section.classList.remove('d-none');
                
                const scopeConfig = window.scopeConfig?.[data.testScope || currentSelectedScope];
                const scopeTitle = scopeConfig?.title || (data.testScope || currentSelectedScope);
                
                let html = '';
                
                // 判断测试结果状态
                const isSuccess = data.testResult === 'SUCCESS' || data.success === true || data.hasPermission === true;
                const isFallback = data.fallbackMode === true;
                const isLocalConfig = data.localConfigResult === true;
                
                // 构建结果显示
                if (isSuccess) {
                    html = `
                        <div class="test-result-item result-success">
                            <span>🎯 测试范围</span>
                            <span><strong>${scopeTitle}</strong></span>
                        </div>
                        <div class="test-result-item result-success">
                            <span>✅ 权限验证</span>
                            <span><strong>通过</strong></span>
                        </div>
                        <div class="test-result-item result-success">
                            <span>👤 当前角色</span>
                            <span><strong>${roleAccounts[currentUser.roleCode]?.displayName}</strong></span>
                        </div>
                        <div class="test-result-item">
                            <span>⏰ 测试时间</span>
                            <span>${new Date().toLocaleString()}</span>
                        </div>
                        ${isFallback ? `
                        <div class="test-result-item result-warning">
                            <span>📡 数据源</span>
                            <span><strong>${isLocalConfig ? '本地配置' : 'API响应'}</strong></span>
                        </div>
                        ` : ''}
                        <div style="margin-top: 15px; padding: 15px; background: #d4edda; border-radius: 8px; color: #155724;">
                            <strong>🎉 测试通过！</strong><br>
                            您具有向<strong>${scopeTitle}</strong>发布通知的权限。
                            可以在此范围内发布各种级别的通知。
                            ${isFallback ? `<br><br><em>⚠️ 注意：由于API调用失败，此结果基于本地权限配置。</em>` : ''}
                        </div>
                    `;
                } else {
                    html = `
                        <div class="test-result-item result-error">
                            <span>🎯 测试范围</span>
                            <span><strong>${scopeTitle}</strong></span>
                        </div>
                        <div class="test-result-item result-error">
                            <span>❌ 权限验证</span>
                            <span><strong>失败</strong></span>
                        </div>
                        <div class="test-result-item result-error">
                            <span>👤 当前角色</span>
                            <span><strong>${roleAccounts[currentUser.roleCode]?.displayName}</strong></span>
                        </div>
                        <div class="test-result-item">
                            <span>⏰ 测试时间</span>
                            <span>${new Date().toLocaleString()}</span>
                        </div>
                        ${isFallback ? `
                        <div class="test-result-item result-warning">
                            <span>📡 数据源</span>
                            <span><strong>${isLocalConfig ? '本地配置' : 'API响应'}</strong></span>
                        </div>
                        ` : ''}
                        ${data.errorMessage ? `
                        <div class="test-result-item result-error">
                            <span>📝 错误信息</span>
                            <span>${data.errorMessage}</span>
                        </div>
                        ` : ''}
                        <div style="margin-top: 15px; padding: 15px; background: #f8d7da; border-radius: 8px; color: #721c24;">
                            <strong>❌ 测试失败！</strong><br>
                            您没有向<strong>${scopeTitle}</strong>发布通知的权限。
                            ${data.errorMessage || '请检查角色权限配置或联系管理员。'}
                            ${isFallback ? `<br><br><em>⚠️ 注意：由于API调用失败，此结果基于本地权限配置。</em>` : ''}
                        </div>
                    `;
                }
                
                container.innerHTML = html;
                addLog('✅ 测试结果已显示', 'success');
                
            } catch (error) {
                addLog(`❌ 显示测试结果失败: ${error.message}`, 'error');
            }
        }

        // 显示加载状态
        function showLoadingState(message = '正在加载...') {
            try {
                // 创建加载遮罩
                let loadingOverlay = document.getElementById('loadingOverlay');
                if (!loadingOverlay) {
                    loadingOverlay = document.createElement('div');
                    loadingOverlay.id = 'loadingOverlay';
                    loadingOverlay.style.cssText = `
                        position: fixed;
                        top: 0;
                        left: 0;
                        width: 100%;
                        height: 100%;
                        background: rgba(0, 0, 0, 0.5);
                        display: flex;
                        align-items: center;
                        justify-content: center;
                        z-index: 10000;
                        backdrop-filter: blur(3px);
                    `;
                    
                    // 安全的加载内容创建，避免XSS
                    const loadingContent = createSafeElement('div');
                    loadingContent.style.cssText = `
                        background: white;
                        padding: 30px;
                        border-radius: 15px;
                        text-align: center;
                        box-shadow: 0 10px 30px rgba(0,0,0,0.3);
                        max-width: 300px;
                    `;
                    
                    const spinner = createSafeElement('div', '', 'spinner');
                    const messageDiv = createSafeElement('div', message);
                    messageDiv.id = 'loadingMessage';
                    messageDiv.style.cssText = 'margin-top: 15px; font-weight: 500; color: #333;';
                    
                    loadingContent.appendChild(spinner);
                    loadingContent.appendChild(messageDiv);
                    loadingOverlay.appendChild(loadingContent);
                    
                    document.body.appendChild(loadingOverlay);
                }
                
                // 更新加载消息
                const messageElement = loadingOverlay.querySelector('#loadingMessage');
                if (messageElement) {
                    messageElement.textContent = message;
                }
                
                loadingOverlay.style.display = 'flex';
                addLog(`🔄 显示加载状态: ${message}`, 'info');
                
            } catch (error) {
                addLog(`❌ 显示加载状态失败: ${error.message}`, 'error');
            }
        }

        // 隐藏加载状态
        function hideLoadingState() {
            try {
                const loadingOverlay = document.getElementById('loadingOverlay');
                if (loadingOverlay) {
                    loadingOverlay.style.display = 'none';
                }
                addLog('✅ 已隐藏加载状态', 'info');
            } catch (error) {
                addLog(`❌ 隐藏加载状态失败: ${error.message}`, 'error');
            }
        }

        /**
         * 增强版错误处理和用户反馈系统 (Phase 6 Enhancement)
         * 提供分层错误处理、自动重试、用户友好的错误信息和恢复建议
         */
        
        // 错误类型枚举
        const ErrorTypes = {
            NETWORK: 'NETWORK',
            AUTH: 'AUTH',
            PERMISSION: 'PERMISSION',
            SERVER: 'SERVER',
            VALIDATION: 'VALIDATION',
            TIMEOUT: 'TIMEOUT',
            UNKNOWN: 'UNKNOWN'
        };
        
        // 错误恢复策略
        const ErrorRecoveryStrategies = {
            [ErrorTypes.NETWORK]: {
                retry: true,
                maxRetries: 3,
                retryDelay: 2000,
                fallback: 'local',
                userAction: '检查网络连接或稍后重试'
            },
            [ErrorTypes.AUTH]: {
                retry: false,
                maxRetries: 0,
                retryDelay: 0,
                fallback: 'relogin',
                userAction: '请重新登录认证'
            },
            [ErrorTypes.PERMISSION]: {
                retry: false,
                maxRetries: 0,
                retryDelay: 0,
                fallback: 'limited',
                userAction: '请联系管理员获取相应权限'
            },
            [ErrorTypes.SERVER]: {
                retry: true,
                maxRetries: 2,
                retryDelay: 3000,
                fallback: 'local',
                userAction: '服务器暂时不可用，请稍后重试'
            },
            [ErrorTypes.TIMEOUT]: {
                retry: true,
                maxRetries: 2,
                retryDelay: 1000,
                fallback: null,
                userAction: '请求超时，正在重试'
            },
            [ErrorTypes.VALIDATION]: {
                retry: false,
                maxRetries: 0,
                retryDelay: 0,
                fallback: null,
                userAction: '请检查输入数据格式'
            },
            [ErrorTypes.UNKNOWN]: {
                retry: true,
                maxRetries: 1,
                retryDelay: 2000,
                fallback: 'local',
                userAction: '发生未知错误，正在尝试恢复'
            }
        };
        
        // 智能错误分析器
        class ErrorAnalyzer {
            static analyzeError(error, context = {}) {
                const errorInfo = {
                    originalError: error,
                    type: ErrorTypes.UNKNOWN,
                    severity: 'medium',
                    message: error.message || '未知错误',
                    context: context,
                    timestamp: new Date().toISOString(),
                    suggestions: [],
                    canRetry: false,
                    userFriendlyMessage: ''
                };
                
                // 网络错误检测
                if (error.message.includes('Failed to fetch') || 
                    error.message.includes('NetworkError') ||
                    error.message.includes('ERR_NETWORK') ||
                    error.name === 'TypeError' && error.message.includes('fetch')) {
                    errorInfo.type = ErrorTypes.NETWORK;
                    errorInfo.severity = 'high';
                    errorInfo.userFriendlyMessage = '网络连接问题，无法访问服务器';
                    errorInfo.suggestions = [
                        '检查网络连接是否正常',
                        '确认服务器是否启动（端口48081、48082）',
                        '检查防火墙设置',
                        '稍后重试'
                    ];
                    errorInfo.canRetry = true;
                }
                // 认证错误检测
                else if (error.message.includes('401') || 
                        error.message.includes('Unauthorized') ||
                        error.message.includes('认证失败') ||
                        error.message.includes('Token')) {
                    errorInfo.type = ErrorTypes.AUTH;
                    errorInfo.severity = 'high';
                    errorInfo.userFriendlyMessage = '身份认证失败或已过期';
                    errorInfo.suggestions = [
                        '请重新登录获取新的认证Token',
                        '检查账号密码是否正确',
                        '确认用户角色权限配置'
                    ];
                    errorInfo.canRetry = false;
                }
                // 权限错误检测
                else if (error.message.includes('403') || 
                        error.message.includes('Forbidden') ||
                        error.message.includes('权限不足')) {
                    errorInfo.type = ErrorTypes.PERMISSION;
                    errorInfo.severity = 'medium';
                    errorInfo.userFriendlyMessage = '权限不足，无法执行此操作';
                    errorInfo.suggestions = [
                        '请联系管理员获取相应权限',
                        '确认当前角色是否有执行该操作的权限',
                        '尝试切换到其他账号'
                    ];
                    errorInfo.canRetry = false;
                }
                // 服务器错误检测
                else if (error.message.includes('500') || 
                        error.message.includes('502') ||
                        error.message.includes('503') ||
                        error.message.includes('Internal Server Error')) {
                    errorInfo.type = ErrorTypes.SERVER;
                    errorInfo.severity = 'high';
                    errorInfo.userFriendlyMessage = '服务器内部错误';
                    errorInfo.suggestions = [
                        '请稍后重试',
                        '如果问题持续存在，请联系技术支持',
                        '检查服务器日志获取详细错误信息'
                    ];
                    errorInfo.canRetry = true;
                }
                // 超时错误检测
                else if (error.message.includes('timeout') || 
                        error.message.includes('超时') ||
                        error.name === 'TimeoutError') {
                    errorInfo.type = ErrorTypes.TIMEOUT;
                    errorInfo.severity = 'medium';
                    errorInfo.userFriendlyMessage = '请求超时，服务器响应时间过长';
                    errorInfo.suggestions = [
                        '网络连接可能较慢，请稍后重试',
                        '检查服务器负载情况',
                        '尝试减少请求数据量'
                    ];
                    errorInfo.canRetry = true;
                }
                // 数据验证错误检测
                else if (error.message.includes('validation') || 
                        error.message.includes('invalid') ||
                        error.message.includes('格式错误') ||
                        error.message.includes('参数错误')) {
                    errorInfo.type = ErrorTypes.VALIDATION;
                    errorInfo.severity = 'low';
                    errorInfo.userFriendlyMessage = '输入数据格式不正确';
                    errorInfo.suggestions = [
                        '请检查输入数据的格式',
                        '确认所有必填字段已正确填写',
                        '参考示例格式重新输入'
                    ];
                    errorInfo.canRetry = false;
                }
                
                return errorInfo;
            }
        }
        
        // 自动重试机制
        class RetryManager {
            static async executeWithRetry(asyncFunction, errorType = ErrorTypes.UNKNOWN, context = {}) {
                const strategy = ErrorRecoveryStrategies[errorType];
                let lastError = null;
                
                for (let attempt = 0; attempt <= (strategy.maxRetries || 0); attempt++) {
                    try {
                        if (attempt > 0) {
                            addLog(`🔄 第${attempt}次重试中...`, 'info');
                            await this.delay(strategy.retryDelay || 1000);
                        }
                        
                        return await asyncFunction();
                    } catch (error) {
                        lastError = error;
                        const errorInfo = ErrorAnalyzer.analyzeError(error, context);
                        
                        if (attempt < (strategy.maxRetries || 0) && errorInfo.canRetry) {
                            addLog(`⚠️ 第${attempt + 1}次尝试失败: ${error.message}`, 'warning');
                            continue;
                        } else {
                            break;
                        }
                    }
                }
                
                // 所有重试都失败了
                throw lastError;
            }
            
            static delay(ms) {
                return new Promise(resolve => setTimeout(resolve, ms));
            }
        }
        
        // 增强版错误提示系统
        class ErrorNotificationSystem {
            static notifications = new Map();
            
            static showEnhancedError(error, context = {}) {
                const errorInfo = ErrorAnalyzer.analyzeError(error, context);
                const strategy = ErrorRecoveryStrategies[errorInfo.type];
                
                // 创建增强版错误通知
                const notification = this.createErrorNotification(errorInfo, strategy, context);
                
                // 记录错误
                this.logError(errorInfo, context);
                
                return notification;
            }
            
            static createErrorNotification(errorInfo, strategy, context) {
                try {
                    // 创建通知容器
                    const notificationId = Date.now().toString();
                    const notification = document.createElement('div');
                    notification.id = `error-notification-${notificationId}`;
                    
                    // 根据错误严重程度设置样式
                    const severityStyles = {
                        low: { bg: '#ffc107', border: '#ff9800' },
                        medium: { bg: '#ff6b6b', border: '#ee5a24' },
                        high: { bg: '#dc3545', border: '#b02a37' }
                    };
                    
                    const style = severityStyles[errorInfo.severity] || severityStyles.medium;
                    
                    notification.style.cssText = `
                        position: fixed;
                        top: 20px;
                        right: 20px;
                        background: linear-gradient(135deg, ${style.bg} 0%, ${style.border} 100%);
                        color: white;
                        padding: 20px;
                        border-radius: 12px;
                        box-shadow: 0 8px 32px rgba(255, 107, 107, 0.3);
                        z-index: 9999;
                        max-width: 450px;
                        word-wrap: break-word;
                        font-size: 14px;
                        line-height: 1.5;
                        border: none;
                        backdrop-filter: blur(10px);
                        animation: slideInRight 0.3s ease-out;
                        transform: translateZ(0);
                    `;
                    
                    // 创建错误内容
                    const content = document.createElement('div');
                    content.innerHTML = `
                        <div style="display: flex; align-items: center; margin-bottom: 12px;">
                            <span style="font-size: 18px; margin-right: 8px;">
                                ${this.getErrorIcon(errorInfo.type)}
                            </span>
                            <strong style="font-size: 16px;">
                                ${this.getErrorTitle(errorInfo.type)}
                            </strong>
                        </div>
                        <div style="margin-bottom: 12px; font-size: 14px;">
                            ${this.sanitizeText(errorInfo.userFriendlyMessage)}
                        </div>
                    `;
                    
                    // 添加建议列表
                    if (errorInfo.suggestions.length > 0) {
                        const suggestionsDiv = document.createElement('div');
                        suggestionsDiv.style.cssText = `
                            background: rgba(255, 255, 255, 0.1);
                            padding: 12px;
                            border-radius: 8px;
                            margin: 12px 0;
                            font-size: 13px;
                        `;
                        
                        let suggestionsHtml = '<div style="font-weight: bold; margin-bottom: 8px;">💡 解决建议：</div>';
                        errorInfo.suggestions.forEach((suggestion, index) => {
                            suggestionsHtml += `<div style="margin: 4px 0;">• ${this.sanitizeText(suggestion)}</div>`;
                        });
                        
                        suggestionsDiv.innerHTML = suggestionsHtml;
                        content.appendChild(suggestionsDiv);
                    }
                    
                    // 添加操作按钮
                    const actionsDiv = document.createElement('div');
                    actionsDiv.style.cssText = `
                        display: flex;
                        gap: 8px;
                        margin-top: 12px;
                        flex-wrap: wrap;
                    `;
                    
                    // 重试按钮
                    if (strategy.retry && context.retryFunction) {
                        const retryBtn = document.createElement('button');
                        retryBtn.innerHTML = '🔄 重试';
                        retryBtn.style.cssText = `
                            background: rgba(255, 255, 255, 0.2);
                            color: white;
                            border: 1px solid rgba(255, 255, 255, 0.3);
                            padding: 6px 12px;
                            border-radius: 6px;
                            cursor: pointer;
                            font-size: 12px;
                            transition: background 0.2s ease;
                        `;
                        
                        retryBtn.onmouseover = () => retryBtn.style.background = 'rgba(255, 255, 255, 0.3)';
                        retryBtn.onmouseout = () => retryBtn.style.background = 'rgba(255, 255, 255, 0.2)';
                        
                        retryBtn.onclick = async () => {
                            try {
                                retryBtn.disabled = true;
                                retryBtn.innerHTML = '⏳ 重试中...';
                                await context.retryFunction();
                                this.closeNotification(notificationId);
                            } catch (retryError) {
                                retryBtn.disabled = false;
                                retryBtn.innerHTML = '🔄 重试';
                                // 显示重试失败的错误
                                this.showEnhancedError(retryError, context);
                            }
                        };
                        
                        actionsDiv.appendChild(retryBtn);
                    }
                    
                    // 详情按钮
                    if (context.showDetails !== false) {
                        const detailsBtn = document.createElement('button');
                        detailsBtn.innerHTML = '📋 详情';
                        detailsBtn.style.cssText = `
                            background: rgba(255, 255, 255, 0.2);
                            color: white;
                            border: 1px solid rgba(255, 255, 255, 0.3);
                            padding: 6px 12px;
                            border-radius: 6px;
                            cursor: pointer;
                            font-size: 12px;
                            transition: background 0.2s ease;
                        `;
                        
                        detailsBtn.onmouseover = () => detailsBtn.style.background = 'rgba(255, 255, 255, 0.3)';
                        detailsBtn.onmouseout = () => detailsBtn.style.background = 'rgba(255, 255, 255, 0.2)';
                        
                        detailsBtn.onclick = () => {
                            this.showErrorDetails(errorInfo);
                        };
                        
                        actionsDiv.appendChild(detailsBtn);
                    }
                    
                    // 关闭按钮
                    const closeBtn = document.createElement('button');
                    closeBtn.innerHTML = '×';
                    closeBtn.style.cssText = `
                        position: absolute;
                        top: 8px;
                        right: 12px;
                        background: none;
                        border: none;
                        color: white;
                        font-size: 20px;
                        font-weight: bold;
                        cursor: pointer;
                        padding: 0;
                        width: 20px;
                        height: 20px;
                        display: flex;
                        align-items: center;
                        justify-content: center;
                        opacity: 0.8;
                        transition: opacity 0.2s ease;
                    `;
                    
                    closeBtn.onmouseover = () => closeBtn.style.opacity = '1';
                    closeBtn.onmouseout = () => closeBtn.style.opacity = '0.8';
                    closeBtn.onclick = () => this.closeNotification(notificationId);
                    
                    // 组装通知
                    notification.appendChild(content);
                    notification.appendChild(actionsDiv);
                    notification.appendChild(closeBtn);
                    
                    document.body.appendChild(notification);
                    
                    // 存储通知引用
                    this.notifications.set(notificationId, notification);
                    
                    // 自动关闭（根据严重程度设置不同的显示时间）
                    const autoCloseDelay = errorInfo.severity === 'high' ? 10000 : 
                                          errorInfo.severity === 'medium' ? 7000 : 5000;
                    
                    setTimeout(() => {
                        this.closeNotification(notificationId);
                    }, autoCloseDelay);
                    
                    return notification;
                    
                } catch (createError) {
                    console.error('创建错误通知失败:', createError);
                    // 备用方案
                    this.showFallbackError(errorInfo.userFriendlyMessage || errorInfo.message);
                    return null;
                }
            }
            
            static getErrorIcon(errorType) {
                const icons = {
                    [ErrorTypes.NETWORK]: '🌐',
                    [ErrorTypes.AUTH]: '🔐',
                    [ErrorTypes.PERMISSION]: '🚫',
                    [ErrorTypes.SERVER]: '⚠️',
                    [ErrorTypes.TIMEOUT]: '⏰',
                    [ErrorTypes.VALIDATION]: '📝',
                    [ErrorTypes.UNKNOWN]: '❌'
                };
                return icons[errorType] || '❌';
            }
            
            static getErrorTitle(errorType) {
                const titles = {
                    [ErrorTypes.NETWORK]: '网络连接错误',
                    [ErrorTypes.AUTH]: '身份认证错误',
                    [ErrorTypes.PERMISSION]: '权限不足',
                    [ErrorTypes.SERVER]: '服务器错误',
                    [ErrorTypes.TIMEOUT]: '请求超时',
                    [ErrorTypes.VALIDATION]: '数据验证错误',
                    [ErrorTypes.UNKNOWN]: '未知错误'
                };
                return titles[errorType] || '系统错误';
            }
            
            static sanitizeText(text) {
                const div = document.createElement('div');
                div.textContent = text;
                return div.innerHTML;
            }
            
            static closeNotification(notificationId) {
                const notification = this.notifications.get(notificationId);
                if (notification && notification.parentNode) {
                    notification.style.animation = 'slideOutRight 0.3s ease-in forwards';
                    setTimeout(() => {
                        if (notification.parentNode) {
                            notification.parentNode.removeChild(notification);
                        }
                        this.notifications.delete(notificationId);
                    }, 300);
                }
            }
            
            static showErrorDetails(errorInfo) {
                const modal = document.createElement('div');
                modal.style.cssText = `
                    position: fixed;
                    top: 0;
                    left: 0;
                    right: 0;
                    bottom: 0;
                    background: rgba(0, 0, 0, 0.8);
                    z-index: 10000;
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    animation: fadeIn 0.3s ease;
                `;
                
                const content = document.createElement('div');
                content.style.cssText = `
                    background: white;
                    padding: 30px;
                    border-radius: 12px;
                    max-width: 600px;
                    max-height: 80vh;
                    overflow-y: auto;
                    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
                    position: relative;
                `;
                
                content.innerHTML = `
                    <h3 style="margin-bottom: 20px; color: #333;">🔍 错误详细信息</h3>
                    <div style="background: #f8f9fa; padding: 15px; border-radius: 8px; margin-bottom: 15px;">
                        <strong>错误类型：</strong> ${this.getErrorTitle(errorInfo.type)}<br>
                        <strong>严重程度：</strong> ${errorInfo.severity}<br>
                        <strong>发生时间：</strong> ${new Date(errorInfo.timestamp).toLocaleString()}
                    </div>
                    <div style="background: #fff3cd; padding: 15px; border-radius: 8px; margin-bottom: 15px;">
                        <strong>错误描述：</strong><br>
                        ${this.sanitizeText(errorInfo.userFriendlyMessage)}
                    </div>
                    <div style="background: #f8d7da; padding: 15px; border-radius: 8px; margin-bottom: 15px;">
                        <strong>原始错误：</strong><br>
                        <code style="font-size: 12px; color: #721c24;">${this.sanitizeText(errorInfo.message)}</code>
                    </div>
                    ${errorInfo.context && Object.keys(errorInfo.context).length > 0 ? `
                    <div style="background: #d1ecf1; padding: 15px; border-radius: 8px; margin-bottom: 15px;">
                        <strong>上下文信息：</strong><br>
                        <pre style="font-size: 12px; margin: 8px 0; white-space: pre-wrap;">${this.sanitizeText(JSON.stringify(errorInfo.context, null, 2))}</pre>
                    </div>
                    ` : ''}
                `;
                
                const closeBtn = document.createElement('button');
                closeBtn.innerHTML = '关闭';
                closeBtn.style.cssText = `
                    background: #007bff;
                    color: white;
                    border: none;
                    padding: 10px 20px;
                    border-radius: 6px;
                    cursor: pointer;
                    font-size: 14px;
                    margin-top: 20px;
                `;
                
                closeBtn.onclick = () => {
                    modal.style.animation = 'fadeOut 0.3s ease forwards';
                    setTimeout(() => {
                        if (modal.parentNode) {
                            modal.parentNode.removeChild(modal);
                        }
                    }, 300);
                };
                
                content.appendChild(closeBtn);
                modal.appendChild(content);
                document.body.appendChild(modal);
                
                // 点击背景关闭
                modal.onclick = (e) => {
                    if (e.target === modal) {
                        closeBtn.click();
                    }
                };
            }
            
            static showFallbackError(message) {
                // 最基础的错误显示备用方案
                console.error('Fallback Error:', message);
                alert(message);
            }
            
            static logError(errorInfo, context) {
                const logMessage = `${this.getErrorIcon(errorInfo.type)} [${errorInfo.type}] ${errorInfo.userFriendlyMessage}`;
                addLog(logMessage, 'error');
                
                // 发送错误到服务器（如果需要）
                if (context.reportToServer !== false) {
                    this.reportErrorToServer(errorInfo, context).catch(reportError => {
                        console.warn('无法将错误报告到服务器:', reportError);
                    });
                }
            }
            
            static async reportErrorToServer(errorInfo, context) {
                // 这里可以实现错误报告到服务器的逻辑
                // 暂时只记录到控制台
                console.warn('错误报告 (未实现服务器报告):', {
                    errorInfo,
                    context,
                    userAgent: navigator.userAgent,
                    url: window.location.href
                });
            }
        }
        
        // API调用增强包装器
        async function enhancedFetch(url, options = {}, context = {}) {
            const enhancedContext = {
                url: url,
                method: options.method || 'GET',
                ...context
            };
            
            try {
                // 设置超时
                const timeout = options.timeout || 30000; // 默认30秒超时
                const controller = new AbortController();
                const timeoutId = setTimeout(() => controller.abort(), timeout);
                
                const fetchOptions = {
                    ...options,
                    signal: controller.signal
                };
                
                const response = await fetch(url, fetchOptions);
                clearTimeout(timeoutId);
                
                if (!response.ok) {
                    const errorText = await response.text();
                    throw new Error(`HTTP ${response.status}: ${response.statusText}${errorText ? ' - ' + errorText : ''}`);
                }
                
                return response;
                
            } catch (error) {
                if (error.name === 'AbortError') {
                    throw new Error(`请求超时 (${(options.timeout || 30000) / 1000}秒)`);
                }
                
                // 使用增强版错误处理
                const errorInfo = ErrorAnalyzer.analyzeError(error, enhancedContext);
                
                // 根据错误类型决定是否自动重试
                if (ErrorRecoveryStrategies[errorInfo.type].retry && !context.noAutoRetry) {
                    try {
                        return await RetryManager.executeWithRetry(
                            () => enhancedFetch(url, {...options, noAutoRetry: true}, context),
                            errorInfo.type,
                            enhancedContext
                        );
                    } catch (retryError) {
                        // 所有重试都失败了，抛出最后的错误
                        throw retryError;
                    }
                }
                
                throw error;
            }
        }
        
        // 兼容性包装器 - 将原有的 showErrorAlert 调用升级为增强版
        const originalShowErrorAlert = showErrorAlert;
        
        // 重新定义 showErrorAlert 为增强版本
        function showEnhancedErrorAlert(message, context = {}) {
            try {
                // 如果传入的是字符串，创建简单的错误对象
                const error = typeof message === 'string' ? new Error(message) : message;
                
                // 使用增强版错误处理系统
                return ErrorNotificationSystem.showEnhancedError(error, {
                    operation: context.operation || '系统操作',
                    showDetails: context.showDetails !== false,
                    reportToServer: context.reportToServer !== false,
                    retryFunction: context.retryFunction,
                    ...context
                });
                
            } catch (enhancedError) {
                console.error('增强版错误处理失败，使用备用方案:', enhancedError);
                // 使用原始的 showErrorAlert 作为备用
                return originalShowErrorAlert(typeof message === 'string' ? message : message.message);
            }
        }

        // 显示错误提示 - 安全版本，避免XSS
        function showErrorAlert(message) {
            try {
                // 创建美化的错误提示
                const alertDiv = document.createElement('div');
                alertDiv.style.cssText = `
                    position: fixed;
                    top: 20px;
                    right: 20px;
                    background: linear-gradient(135deg, #ff6b6b 0%, #ee5a24 100%);
                    color: white;
                    padding: 20px;
                    border-radius: 12px;
                    box-shadow: 0 8px 25px rgba(255, 107, 107, 0.3);
                    max-width: 400px;
                    z-index: 10001;
                    font-weight: 500;
                    animation: slideInRight 0.3s ease-out;
                `;
                
                // 创建内容容器
                const contentDiv = document.createElement('div');
                contentDiv.style.cssText = 'display: flex; align-items: flex-start; gap: 12px;';
                
                // 创建图标
                const iconDiv = document.createElement('div');
                iconDiv.style.cssText = 'font-size: 1.3rem;';
                iconDiv.textContent = '❌';
                
                // 创建文本容器
                const textDiv = document.createElement('div');
                textDiv.style.cssText = 'flex: 1;';
                
                // 创建标题
                const titleDiv = document.createElement('div');
                titleDiv.style.cssText = 'font-weight: 600; margin-bottom: 8px;';
                titleDiv.textContent = '操作失败';
                
                // 创建消息内容
                const messageDiv = document.createElement('div');
                messageDiv.style.cssText = 'font-size: 0.9rem; line-height: 1.4; opacity: 0.95; white-space: pre-line;';
                messageDiv.textContent = message;
                
                // 创建关闭按钮
                const closeBtn = document.createElement('button');
                closeBtn.style.cssText = 'background: none; border: none; color: white; font-size: 1.2rem; cursor: pointer; padding: 0; line-height: 1;';
                closeBtn.textContent = '✕';
                closeBtn.onclick = () => alertDiv.remove();
                
                // 组装元素
                textDiv.appendChild(titleDiv);
                textDiv.appendChild(messageDiv);
                contentDiv.appendChild(iconDiv);
                contentDiv.appendChild(textDiv);
                contentDiv.appendChild(closeBtn);
                alertDiv.appendChild(contentDiv);
                
                document.body.appendChild(alertDiv);
                
                // 自动消失
                setTimeout(() => {
                    if (alertDiv.parentElement) {
                        alertDiv.style.animation = 'slideOutRight 0.3s ease-out';
                        setTimeout(() => alertDiv.remove(), 300);
                    }
                }, 8000);
                
                addLog(`🚨 显示错误提示: ${message}`, 'error');
                
            } catch (error) {
                // 备用方案：使用原生alert
                alert(`操作失败：\n\n${message}`);
                addLog(`❌ 创建错误提示失败，使用备用方案: ${error.message}`, 'error');
            }
        }

        // 更新权限矩阵与API数据
        function updateMatrixWithAPIData(apiData) {
            if (!apiData) return;
            
            try {
                addLog('🔄 使用API数据更新权限矩阵...', 'info');
                
                // 获取矩阵指示器元素
                const indicator = document.getElementById('matrixUpdateIndicator');
                
                // 更新矩阵指示器 - 安全版本，避免XSS
                if (indicator) {
                    const timestamp = new Date().toLocaleTimeString();
                    indicator.textContent = '';
                    const span = createSafeElement('span', `(✅ API数据已更新 ${timestamp})`);
                    span.style.color = '#28a745';
                    indicator.appendChild(span);
                }
                
                // 如果API返回了完整的权限矩阵，可以在这里更新
                if (apiData.rolePermissions) {
                    addLog('📊 检测到完整权限矩阵数据', 'info');
                    // 这里可以扩展来处理完整的权限矩阵更新
                }
                
                addLog('✅ 权限矩阵API数据更新完成', 'success');
                
            } catch (error) {
                addLog(`❌ 更新权限矩阵失败: ${error.message}`, 'error');
            }
        }

        // 添加CSS动画样式
        const animationStyles = document.createElement('style');
        animationStyles.textContent = `
            @keyframes slideInRight {
                from {
                    opacity: 0;
                    transform: translateX(100%);
                }
                to {
                    opacity: 1;
                    transform: translateX(0);
                }
            }
            
            @keyframes slideOutRight {
                from {
                    opacity: 1;
                    transform: translateX(0);
                }
                to {
                    opacity: 0;
                    transform: translateX(100%);
                }
            }
            
            @keyframes fadeIn {
                from {
                    opacity: 0;
                }
                to {
                    opacity: 1;
                }
            }
            
            @keyframes fadeOut {
                from {
                    opacity: 1;
                }
                to {
                    opacity: 0;
                }
            }
            
            @keyframes bounce {
                0%, 20%, 50%, 80%, 100% {
                    transform: translateY(0);
                }
                40% {
                    transform: translateY(-10px);
                }
                60% {
                    transform: translateY(-5px);
                }
            }
            
            @keyframes pulse {
                0% {
                    transform: scale(1);
                }
                50% {
                    transform: scale(1.05);
                }
                100% {
                    transform: scale(1);
                }
            }
        `;
        document.head.appendChild(animationStyles);

        // 更新用户信息面板 - 安全版本，避免XSS
        function updateUserInfoPanel() {
            if (!currentUser) return;
            
            const userInfo = document.getElementById('userInfo');
            
            if (!userInfo) {
                addLog('❌ 用户信息面板元素不存在', 'error');
                return;
            }
            
            const roleIcon = getRoleIcon(currentUser.roleCode);
            const roleDisplay = roleAccounts[currentUser.roleCode]?.displayName || currentUser.roleCode;
            const availableCount = currentAvailableScopes.length;
            const displayName = currentUser.realName || currentUser.username || '未知用户';
            
            try {
                // 清空现有内容
                userInfo.textContent = ''; // 安全的内容清空
                
                // 创建用户头像
                const userAvatar = document.createElement('div');
                userAvatar.className = 'user-avatar';
                userAvatar.textContent = roleIcon;
                
                // 创建用户详情容器
                const userDetails = document.createElement('div');
                userDetails.className = 'user-details';
                
                // 创建用户姓名
                const userName = document.createElement('div');
                userName.className = 'user-name';
                userName.textContent = displayName;
                
                // 创建角色信息
                const userRole = document.createElement('div');
                userRole.className = 'user-role';
                userRole.textContent = roleDisplay;
                
                // 创建范围统计
                const scopeStats = document.createElement('div');
                scopeStats.style.cssText = 'margin-top: 8px; font-size: 0.85rem; opacity: 0.9;';
                scopeStats.textContent = `🎯 可用范围：${availableCount}个`;
                
                // 组装元素
                userDetails.appendChild(userName);
                userDetails.appendChild(userRole);
                userDetails.appendChild(scopeStats);
                
                userInfo.appendChild(userAvatar);
                userInfo.appendChild(userDetails);
                
                addLog('✅ 用户信息面板已更新（安全模式）', 'success');
            } catch (error) {
                addLog(`❌ 更新用户信息面板失败: ${error.message}`, 'error');
            }
        }

        // 更新范围权限面板 - 安全版本，避免XSS
        function updateScopePermissionPanel() {
            if (!currentUser) return;
            
            const permissionList = document.getElementById('scopePermissionList');
            
            if (!permissionList) {
                addLog('❌ 范围权限列表元素不存在', 'error');
                return;
            }
            
            const userScopes = currentAvailableScopes;
            const allScopes = ['SCHOOL_WIDE', 'DEPARTMENT', 'CLASS', 'GRADE'];
            
            try {
                // 清空现有内容
                permissionList.textContent = ''; // 安全的内容清空
                
                allScopes.forEach(scope => {
                    const config = scopeConfig[scope];
                    const hasPermission = userScopes.includes(scope);
                    
                    // 创建列表项
                    const listItem = document.createElement('li');
                    
                    // 创建标题部分
                    const titleSpan = document.createElement('span');
                    titleSpan.textContent = `${config.icon} ${config.title}`;
                    
                    // 创建权限状态部分
                    const statusSpan = document.createElement('span');
                    statusSpan.className = hasPermission ? 'permission-check' : 'permission-cross';
                    statusSpan.textContent = hasPermission ? '✓' : '✗';
                    
                    listItem.appendChild(titleSpan);
                    listItem.appendChild(statusSpan);
                    permissionList.appendChild(listItem);
                });
                
                addLog('✅ 范围权限面板已更新（安全模式）', 'success');
            } catch (error) {
                addLog(`❌ 更新范围权限面板失败: ${error.message}`, 'error');
            }
        }

        // 切换矩阵视图模式（新增）
        function switchMatrixView(viewType) {
            addLog(`🔄 切换矩阵视图模式: ${viewType}`, 'info');
            
            try {
                // 更新标签页状态
                document.querySelectorAll('.permission-tab').forEach(tab => {
                    tab.classList.remove('active');
                });
                document.getElementById(viewType + 'Tab').classList.add('active');
                
                // 隐藏所有视图
                document.querySelectorAll('.matrix-view').forEach(view => {
                    view.style.display = 'none';
                });
                
                // 显示选中的视图
                const targetView = document.getElementById(viewType + 'View');
                if (targetView) {
                    targetView.style.display = 'block';
                    currentMatrixView = viewType;
                    
                    // 根据视图类型执行相应的初始化
                    switch (viewType) {
                        case 'table':
                            // 表格视图已经初始化，无需额外操作
                            break;
                        case 'heatmap':
                            initializePermissionHeatmap();
                            break;
                        case 'charts':
                            initializePermissionCharts();
                            break;
                        case 'comparison':
                            initializePermissionComparison();
                            break;
                    }
                    
                    addLog(`✅ 已切换到${viewType}视图`, 'success');
                } else {
                    throw new Error(`视图容器不存在: ${viewType}View`);
                }
                
            } catch (error) {
                addLog(`❌ 切换矩阵视图失败: ${error.message}`, 'error');
            }
        }

        // 初始化权限热力图（新增）
        function initializePermissionHeatmap() {
            addLog('🔥 初始化权限热力图...', 'info');
            
            try {
                const container = document.getElementById('permissionHeatmap');
                if (!container) {
                    throw new Error('热力图容器不存在');
                }

                const roles = Object.keys(ENHANCED_PERMISSION_MATRIX);
                const scopes = ['SCHOOL_WIDE', 'DEPARTMENT', 'CLASS', 'GRADE'];
                
                let heatmapHTML = `<div class="heatmap-container">`;
                
                // 表头
                heatmapHTML += `<div class="heatmap-cell heatmap-header">角色\\范围</div>`;
                scopes.forEach(scope => {
                    const config = scopeConfig[scope];
                    heatmapHTML += `<div class="heatmap-cell heatmap-header">${config.icon}<br>${config.title}</div>`;
                });
                
                // 数据行
                roles.forEach(role => {
                    const roleDisplay = roleAccounts[role]?.displayName || role;
                    const roleIcon = getRoleIcon(role);
                    
                    heatmapHTML += `<div class="heatmap-cell heatmap-role-header">${roleIcon}<br>${roleDisplay}</div>`;
                    
                    scopes.forEach(scope => {
                        const allowedLevels = ENHANCED_PERMISSION_MATRIX[role][scope] || [];
                        const levelCount = allowedLevels.length;
                        const cellClass = `heatmap-level-${levelCount}`;
                        const cellContent = levelCount > 0 ? `${levelCount}级` : '无权限';
                        
                        heatmapHTML += `
                            <div class="heatmap-cell ${cellClass}" 
                                 onclick="showHeatmapCellDetail('${role}', '${scope}', ${JSON.stringify(allowedLevels).replace(/"/g, "&quot;")})"
                                 data-role="${role}" 
                                 data-scope="${scope}"
                                 title="${roleDisplay} - ${scopeConfig[scope].title}: ${levelCount}个级别权限">
                                ${cellContent}
                            </div>
                        `;
                    });
                });
                
                heatmapHTML += `</div>`;
                
                // 添加图例
                heatmapHTML += `
                    <div style="margin-top: 20px; display: flex; justify-content: center; gap: 20px; flex-wrap: wrap;">
                        <div style="display: flex; align-items: center; gap: 8px;">
                            <div class="heatmap-cell heatmap-level-0" style="width: 20px; height: 20px; min-height: 20px;"></div>
                            <span>无权限</span>
                        </div>
                        <div style="display: flex; align-items: center; gap: 8px;">
                            <div class="heatmap-cell heatmap-level-1" style="width: 20px; height: 20px; min-height: 20px;"></div>
                            <span>1级权限</span>
                        </div>
                        <div style="display: flex; align-items: center; gap: 8px;">
                            <div class="heatmap-cell heatmap-level-2" style="width: 20px; height: 20px; min-height: 20px;"></div>
                            <span>2级权限</span>
                        </div>
                        <div style="display: flex; align-items: center; gap: 8px;">
                            <div class="heatmap-cell heatmap-level-3" style="width: 20px; height: 20px; min-height: 20px;"></div>
                            <span>3级权限</span>
                        </div>
                        <div style="display: flex; align-items: center; gap: 8px;">
                            <div class="heatmap-cell heatmap-level-4" style="width: 20px; height: 20px; min-height: 20px;"></div>
                            <span>4级权限</span>
                        </div>
                    </div>
                `;
                
                container.innerHTML = heatmapHTML;
                addLog('✅ 权限热力图初始化完成', 'success');
                
            } catch (error) {
                addLog(`❌ 初始化权限热力图失败: ${error.message}`, 'error');
            }
        }

        // 显示热力图单元格详情（新增）
        function showHeatmapCellDetail(role, scope, allowedLevelsStr) {
            try {
                const allowedLevels = JSON.parse(allowedLevelsStr);
                const roleDisplay = roleAccounts[role]?.displayName || role;
                const scopeTitle = scopeConfig[scope]?.title || scope;
                
                showPermissionDetailModal(role, scope, roleDisplay, scopeTitle, allowedLevels);
                addLog(`🔍 热力图单元格详情: ${roleDisplay} - ${scopeTitle}`, 'info');
                
            } catch (error) {
                addLog(`❌ 显示热力图单元格详情失败: ${error.message}`, 'error');
            }
        }

        // 初始化权限统计图表（新增）
        function initializePermissionCharts() {
            addLog('📊 初始化权限统计图表...', 'info');
            
            try {
                // 清理现有的图表实例
                Object.values(chartInstances).forEach(chart => {
                    if (chart && typeof chart.destroy === 'function') {
                        chart.destroy();
                    }
                });
                chartInstances = {};
                
                // 生成统计数据
                generateStatisticsCards();
                
                // 初始化各个图表
                setTimeout(() => {
                    initializeRolePermissionChart();
                    initializeScopeCoverageChart();
                    initializePermissionTrendChart();
                    initializeCombinationAnalysisChart();
                }, 100);
                
                addLog('✅ 权限统计图表初始化完成', 'success');
                
            } catch (error) {
                addLog(`❌ 初始化权限统计图表失败: ${error.message}`, 'error');
            }
        }

        // 生成统计数据卡片（新增）
        function generateStatisticsCards() {
            const container = document.getElementById('statisticsGrid');
            if (!container) return;
            
            try {
                const roles = Object.keys(ENHANCED_PERMISSION_MATRIX);
                const scopes = ['SCHOOL_WIDE', 'DEPARTMENT', 'CLASS', 'GRADE'];
                
                // 计算统计数据
                let totalPermissions = 0;
                let totalCombinations = 0;
                let maxPermissionsRole = '';
                let maxPermissionsCount = 0;
                
                roles.forEach(role => {
                    let rolePermissionCount = 0;
                    scopes.forEach(scope => {
                        const levelCount = ENHANCED_PERMISSION_MATRIX[role][scope]?.length || 0;
                        rolePermissionCount += levelCount;
                        totalPermissions += levelCount;
                        if (levelCount > 0) totalCombinations++;
                    });
                    
                    if (rolePermissionCount > maxPermissionsCount) {
                        maxPermissionsCount = rolePermissionCount;
                        maxPermissionsRole = roleAccounts[role]?.displayName || role;
                    }
                });
                
                const averagePermissions = (totalPermissions / roles.length).toFixed(1);
                
                // 安全的统计卡片创建，避免XSS
                container.innerHTML = ''; // 清空现有内容
                
                const stats = [
                    { number: roles.length, label: '角色数量' },
                    { number: scopes.length, label: '范围类型' },
                    { number: totalCombinations, label: '有效权限组合' },
                    { number: totalPermissions, label: '总权限级别数' },
                    { number: averagePermissions, label: '平均权限数' },
                    { number: maxPermissionsRole, label: '最高权限角色', small: true }
                ];
                
                stats.forEach(stat => {
                    const cardDiv = createSafeElement('div', '', 'stat-card');
                    
                    const numberDiv = createSafeElement('div', stat.number.toString(), 'stat-number');
                    if (stat.small) {
                        numberDiv.style.fontSize = '1rem';
                    }
                    
                    const labelDiv = createSafeElement('div', stat.label, 'stat-label');
                    
                    cardDiv.appendChild(numberDiv);
                    cardDiv.appendChild(labelDiv);
                    container.appendChild(cardDiv);
                });
                
            } catch (error) {
                addLog(`❌ 生成统计数据卡片失败: ${error.message}`, 'error');
            }
        }

        // 初始化角色权限分布图表（新增）
        function initializeRolePermissionChart() {
            const ctx = document.getElementById('rolePermissionChart');
            if (!ctx) return;
            
            try {
                const roles = Object.keys(ENHANCED_PERMISSION_MATRIX);
                const scopes = ['SCHOOL_WIDE', 'DEPARTMENT', 'CLASS', 'GRADE'];
                
                const data = roles.map(role => {
                    const roleDisplay = roleAccounts[role]?.displayName || role;
                    let totalPermissions = 0;
                    scopes.forEach(scope => {
                        totalPermissions += ENHANCED_PERMISSION_MATRIX[role][scope]?.length || 0;
                    });
                    return { role: roleDisplay, count: totalPermissions };
                });
                
                const colors = ['#ff6b6b', '#feca57', '#48dbfb', '#1dd1a1', '#ff9ff3'];
                
                chartInstances.rolePermissionChart = new Chart(ctx, {
                    type: 'doughnut',
                    data: {
                        labels: data.map(d => d.role),
                        datasets: [{
                            data: data.map(d => d.count),
                            backgroundColor: colors,
                            borderWidth: 2,
                            borderColor: '#fff'
                        }]
                    },
                    options: {
                        responsive: true,
                        maintainAspectRatio: false,
                        plugins: {
                            legend: {
                                position: 'bottom',
                                labels: {
                                    padding: 15,
                                    usePointStyle: true
                                }
                            },
                            tooltip: {
                                callbacks: {
                                    label: function(context) {
                                        return `${context.label}: ${context.parsed}个权限级别`;
                                    }
                                }
                            }
                        }
                    }
                });
                
            } catch (error) {
                addLog(`❌ 初始化角色权限分布图表失败: ${error.message}`, 'error');
            }
        }

        // 初始化范围覆盖统计图表（新增）
        function initializeScopeCoverageChart() {
            const ctx = document.getElementById('scopeCoverageChart');
            if (!ctx) return;
            
            try {
                const roles = Object.keys(ENHANCED_PERMISSION_MATRIX);
                const scopes = ['SCHOOL_WIDE', 'DEPARTMENT', 'CLASS', 'GRADE'];
                
                const scopeData = scopes.map(scope => {
                    const scopeTitle = scopeConfig[scope]?.title || scope;
                    let totalLevels = 0;
                    let roleCount = 0;
                    
                    roles.forEach(role => {
                        const levels = ENHANCED_PERMISSION_MATRIX[role][scope]?.length || 0;
                        if (levels > 0) {
                            totalLevels += levels;
                            roleCount++;
                        }
                    });
                    
                    return { scope: scopeTitle, levels: totalLevels, roles: roleCount };
                });
                
                chartInstances.scopeCoverageChart = new Chart(ctx, {
                    type: 'bar',
                    data: {
                        labels: scopeData.map(d => d.scope),
                        datasets: [
                            {
                                label: '总权限级别数',
                                data: scopeData.map(d => d.levels),
                                backgroundColor: 'rgba(102, 126, 234, 0.7)',
                                borderColor: 'rgba(102, 126, 234, 1)',
                                borderWidth: 2
                            },
                            {
                                label: '拥有权限角色数',
                                data: scopeData.map(d => d.roles),
                                backgroundColor: 'rgba(255, 107, 107, 0.7)',
                                borderColor: 'rgba(255, 107, 107, 1)',
                                borderWidth: 2
                            }
                        ]
                    },
                    options: {
                        responsive: true,
                        maintainAspectRatio: false,
                        plugins: {
                            legend: {
                                position: 'top',
                                labels: {
                                    padding: 15
                                }
                            }
                        },
                        scales: {
                            y: {
                                beginAtZero: true,
                                ticks: {
                                    stepSize: 1
                                }
                            }
                        }
                    }
                });
                
            } catch (error) {
                addLog(`❌ 初始化范围覆盖统计图表失败: ${error.message}`, 'error');
            }
        }

        // 初始化权限层级趋势图表（新增）
        function initializePermissionTrendChart() {
            const ctx = document.getElementById('permissionTrendChart');
            if (!ctx) return;
            
            try {
                const roles = Object.keys(ENHANCED_PERMISSION_MATRIX);
                const scopes = ['SCHOOL_WIDE', 'DEPARTMENT', 'CLASS', 'GRADE'];
                
                const datasets = scopes.map((scope, index) => {
                    const scopeTitle = scopeConfig[scope]?.title || scope;
                    const colors = ['#ff6b6b', '#feca57', '#48dbfb', '#1dd1a1'];
                    
                    return {
                        label: scopeTitle,
                        data: roles.map(role => {
                            return ENHANCED_PERMISSION_MATRIX[role][scope]?.length || 0;
                        }),
                        borderColor: colors[index],
                        backgroundColor: colors[index] + '33',
                        fill: false,
                        tension: 0.4
                    };
                });
                
                chartInstances.permissionTrendChart = new Chart(ctx, {
                    type: 'line',
                    data: {
                        labels: roles.map(role => roleAccounts[role]?.displayName || role),
                        datasets: datasets
                    },
                    options: {
                        responsive: true,
                        maintainAspectRatio: false,
                        plugins: {
                            legend: {
                                position: 'top',
                                labels: {
                                    padding: 15
                                }
                            }
                        },
                        scales: {
                            y: {
                                beginAtZero: true,
                                max: 4,
                                ticks: {
                                    stepSize: 1
                                },
                                title: {
                                    display: true,
                                    text: '权限级别数量'
                                }
                            },
                            x: {
                                title: {
                                    display: true,
                                    text: '角色层级'
                                }
                            }
                        }
                    }
                });
                
            } catch (error) {
                addLog(`❌ 初始化权限层级趋势图表失败: ${error.message}`, 'error');
            }
        }

        // 初始化权限组合分析图表（新增）
        function initializeCombinationAnalysisChart() {
            const ctx = document.getElementById('combinationAnalysisChart');
            if (!ctx) return;
            
            try {
                const roles = Object.keys(ENHANCED_PERMISSION_MATRIX);
                const scopes = ['SCHOOL_WIDE', 'DEPARTMENT', 'CLASS', 'GRADE'];
                
                // 计算每个权限级别的分布
                let levelDistribution = { 1: 0, 2: 0, 3: 0, 4: 0 };
                
                roles.forEach(role => {
                    scopes.forEach(scope => {
                        const levels = ENHANCED_PERMISSION_MATRIX[role][scope] || [];
                        levels.forEach(level => {
                            levelDistribution[level]++;
                        });
                    });
                });
                
                const levelColors = {
                    1: '#ff6b6b',  // 紧急
                    2: '#feca57',  // 重要
                    3: '#48dbfb',  // 常规
                    4: '#1dd1a1'   // 提醒
                };
                
                chartInstances.combinationAnalysisChart = new Chart(ctx, {
                    type: 'pie',
                    data: {
                        labels: Object.keys(levelDistribution).map(level => NOTIFICATION_LEVELS[level].name),
                        datasets: [{
                            data: Object.values(levelDistribution),
                            backgroundColor: Object.keys(levelDistribution).map(level => levelColors[level]),
                            borderWidth: 2,
                            borderColor: '#fff'
                        }]
                    },
                    options: {
                        responsive: true,
                        maintainAspectRatio: false,
                        plugins: {
                            legend: {
                                position: 'bottom',
                                labels: {
                                    padding: 15,
                                    usePointStyle: true
                                }
                            },
                            tooltip: {
                                callbacks: {
                                    label: function(context) {
                                        const total = context.dataset.data.reduce((sum, val) => sum + val, 0);
                                        const percentage = ((context.parsed / total) * 100).toFixed(1);
                                        return `${context.label}: ${context.parsed}个权限 (${percentage}%)`;
                                    }
                                }
                            }
                        }
                    }
                });
                
            } catch (error) {
                addLog(`❌ 初始化权限组合分析图表失败: ${error.message}`, 'error');
            }
        }

        // 初始化权限对比表格（新增）
        function initializePermissionComparison() {
            addLog('⚖️ 初始化权限对比分析...', 'info');
            
            try {
                const container = document.getElementById('permissionComparison');
                if (!container) {
                    throw new Error('权限对比容器不存在');
                }

                const roles = Object.keys(ENHANCED_PERMISSION_MATRIX);
                const scopes = ['SCHOOL_WIDE', 'DEPARTMENT', 'CLASS', 'GRADE'];
                
                let comparisonHTML = `
                    <div style="margin-bottom: 30px; text-align: center; color: #666; font-size: 0.95rem;">
                        📊 详细对比5个角色在4个范围内的权限级别分布，清楚展现权限层级关系
                    </div>
                `;
                
                // 权限对比表格
                comparisonHTML += `<table class="comparison-table">`;
                
                // 表头
                comparisonHTML += `
                    <thead>
                        <tr>
                            <th rowspan="2">角色</th>
                            <th rowspan="2">总权限数</th>
                            <th colspan="4">各范围权限级别分布</th>
                            <th rowspan="2">权限特点</th>
                        </tr>
                        <tr>
                            ${scopes.map(scope => `<th>${scopeConfig[scope].icon}<br>${scopeConfig[scope].title}</th>`).join('')}
                        </tr>
                    </thead>
                `;
                
                // 数据行
                comparisonHTML += `<tbody>`;
                roles.forEach((role, roleIndex) => {
                    const roleDisplay = roleAccounts[role]?.displayName || role;
                    const roleIcon = getRoleIcon(role);
                    
                    // 计算总权限数
                    let totalPermissions = 0;
                    scopes.forEach(scope => {
                        totalPermissions += ENHANCED_PERMISSION_MATRIX[role][scope]?.length || 0;
                    });
                    
                    // 权限特点描述
                    const permissionFeatures = {
                        'PRINCIPAL': '全权限管理，可处理所有级别紧急事务',
                        'ACADEMIC_ADMIN': '教务统筹管理，1级权限需审批',
                        'TEACHER': '专业教学管理，负责日常教务工作',
                        'CLASS_TEACHER': '班级年级管理，学生事务专员',
                        'STUDENT': '基础班级权限，组织学生活动'
                    };
                    
                    comparisonHTML += `
                        <tr style="background: ${roleIndex % 2 === 0 ? '#fff' : '#f8f9fa'};">
                            <td style="font-weight: 600; text-align: left; padding-left: 15px;">
                                ${roleIcon} ${roleDisplay}
                            </td>
                            <td style="font-weight: 600; color: #667eea;">
                                ${totalPermissions} 级别
                            </td>
                    `;
                    
                    // 各范围权限数据
                    scopes.forEach(scope => {
                        const levels = ENHANCED_PERMISSION_MATRIX[role][scope] || [];
                        const levelCount = levels.length;
                        const cellStyle = levelCount > 0 ? 
                            `background: rgba(40, 167, 69, 0.1); color: #28a745; font-weight: 600;` : 
                            `background: rgba(220, 53, 69, 0.1); color: #dc3545;`;
                        
                        const levelDetails = levels.length > 0 ? 
                            levels.map(l => NOTIFICATION_LEVELS[l].name).join('、') : 
                            '无权限';
                        
                        comparisonHTML += `
                            <td style="${cellStyle}" 
                                title="${roleDisplay} - ${scopeConfig[scope].title}: ${levelDetails}">
                                ${levelCount > 0 ? `${levelCount}级` : '❌'}
                            </td>
                        `;
                    });
                    
                    comparisonHTML += `
                            <td style="text-align: left; padding-left: 15px; font-size: 0.9rem; color: #666;">
                                ${permissionFeatures[role] || '角色权限'}
                            </td>
                        </tr>
                    `;
                });
                comparisonHTML += `</tbody></table>`;
                
                // 权限层级分析
                comparisonHTML += `
                    <div style="margin-top: 30px; padding: 25px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); border-radius: 15px; color: white;">
                        <h4 style="color: white; margin-bottom: 20px; text-align: center;">🏆 权限层级深度分析</h4>
                        <div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 20px;">
                            <div style="background: rgba(255,255,255,0.1); padding: 20px; border-radius: 12px;">
                                <div style="font-size: 1.2rem; font-weight: 600; margin-bottom: 10px;">📊 权限分布特征</div>
                                <div style="font-size: 0.95rem; line-height: 1.5; opacity: 0.9;">
                                    • 校长拥有最高权限（16级别）<br>
                                    • 教务主任次级管理权限（9级别）<br>
                                    • 教师专业领域权限（4级别）<br>
                                    • 班主任班级事务权限（4级别）<br>
                                    • 学生基础参与权限（1级别）
                                </div>
                            </div>
                            <div style="background: rgba(255,255,255,0.1); padding: 20px; border-radius: 12px;">
                                <div style="font-size: 1.2rem; font-weight: 600; margin-bottom: 10px;">🎯 设计原则体现</div>
                                <div style="font-size: 0.95rem; line-height: 1.5; opacity: 0.9;">
                                    • 最小权限原则：各角色权限最小化<br>
                                    • 专业分工：不同角色专业权限<br>
                                    • 层级管理：清楚的管理层次<br>
                                    • 安全控制：防止权限滥用<br>
                                    • 效率优化：快速决策执行
                                </div>
                            </div>
                        </div>
                    </div>
                `;
                
                container.innerHTML = comparisonHTML;
                addLog('✅ 权限对比分析初始化完成', 'success');
                
            } catch (error) {
                addLog(`❌ 初始化权限对比分析失败: ${error.message}`, 'error');
            }
        }

        // 导航到其他Phase
        function navigateToPhase(phase) {
            const phaseMap = {
                'phase1': 'phase1-connection-working.html',
                'phase2': 'phase2-authentication-enhanced.html', 
                'phase3': 'phase3-notification-publish.html',
                'phase4': 'phase4-notification-list.html',
                'phase5': 'phase5-notification-approval.html'
            };
            
            if (phaseMap[phase]) {
                if (currentUser && currentToken) {
                    // 保存当前认证状态
                    const jumpContext = {
                        fromPhase: 'phase6',
                        user: currentUser,
                        token: currentToken,
                        timestamp: Date.now()
                    };
                    localStorage.setItem(`${phase}JumpContext`, JSON.stringify(jumpContext));
                    sessionStorage.setItem(`${phase}JumpContext`, JSON.stringify(jumpContext));
                }
                window.location.href = phaseMap[phase];
            }
        }

        // 继承前一阶段的认证状态
        function inheritAuthFromPreviousPhase() {
            try {
                const jumpContext = localStorage.getItem('phase6JumpContext') || 
                                   sessionStorage.getItem('phase6JumpContext');
                
                if (jumpContext) {
                    const context = JSON.parse(jumpContext);
                    if (context.user && context.token) {
                        currentUser = context.user;
                        currentToken = context.token;
                        
                        addLog(`✅ 成功继承认证状态: ${context.user.name || context.user.username} (${context.user.roleCode})`, 'success');
                        
                        // 更新UI状态
                        updateAuthStatus();
                        showMainContent();
                        initializeScopePermissions();
                        
                        return true;
                    }
                }
            } catch (error) {
                addLog(`⚠️ 继承认证状态失败: ${error.message}`, 'warning');
            }
            return false;
        }

        // 切换认证区域显示
        function toggleAuthSection() {
            const authSection = document.getElementById('authSection');
            authSection.classList.toggle('hidden');
        }

        // 切换到下一角色
        function switchToNextRole() {
            const roles = ['PRINCIPAL', 'ACADEMIC_ADMIN', 'TEACHER', 'CLASS_TEACHER', 'STUDENT'];
            const currentRoleIndex = roles.indexOf(currentUser?.roleCode || 'PRINCIPAL');
            const nextRoleIndex = (currentRoleIndex + 1) % roles.length;
            const nextRole = roles[nextRoleIndex];
            
            // 更新选择框
            document.getElementById('roleSelect').value = nextRole;
            
            addLog(`🔄 准备切换到下一角色: ${roleAccounts[nextRole].displayName}`, 'info');
            
            // 自动重新认证
            setTimeout(() => {
                authenticateInPage();
            }, 500);
        }

        // 测试所有范围权限
        async function testAllScopePermissions() {
            if (!currentUser || !currentToken) {
                addLog('❌ 用户未认证，无法执行测试', 'error');
                return;
            }
            
            addLog('🧪 开始测试所有范围权限...', 'info');
            
            const allScopes = ['SCHOOL_WIDE', 'DEPARTMENT', 'CLASS', 'GRADE'];
            const results = [];
            
            for (const scope of allScopes) {
                try {
                    addLog(`🔍 测试范围: ${scopeConfig[scope].title}`, 'info');
                    
                    const hasPermission = currentAvailableScopes.includes(scope);
                    const result = {
                        scope: scope,
                        scopeTitle: scopeConfig[scope].title,
                        hasPermission: hasPermission,
                        status: hasPermission ? 'SUCCESS' : 'NO_PERMISSION'
                    };
                    
                    results.push(result);
                    
                    // 添加延迟避免请求过快
                    await new Promise(resolve => setTimeout(resolve, 200));
                    
                } catch (error) {
                    addLog(`❌ 测试范围${scope}时出错: ${error.message}`, 'error');
                    results.push({
                        scope: scope,
                        scopeTitle: scopeConfig[scope].title,
                        hasPermission: false,
                        status: 'ERROR',
                        error: error.message
                    });
                }
            }
            
            showAllTestResults(results);
            addLog('✅ 所有范围权限测试完成', 'success');
        }

        // 显示所有测试结果
        function showAllTestResults(results) {
            const container = document.getElementById('testResultsContent');
            const section = document.getElementById('testResultsSection');
            
            if (!container || !section) return;
            
            try {
                section.classList.remove('d-none');
                
                const successCount = results.filter(r => r.hasPermission).length;
                const totalCount = results.length;
                
                let html = `
                    <div class="test-result-item">
                        <span>🎯 测试类型</span>
                        <span><strong>全部范围权限测试</strong></span>
                    </div>
                    <div class="test-result-item">
                        <span>📊 测试结果</span>
                        <span><strong>${successCount}/${totalCount} 通过</strong></span>
                    </div>
                    <div class="test-result-item">
                        <span>👤 当前角色</span>
                        <span><strong>${roleAccounts[currentUser.roleCode]?.displayName}</strong></span>
                    </div>
                    <div class="test-result-item">
                        <span>⏰ 测试时间</span>
                        <span>${new Date().toLocaleString()}</span>
                    </div>
                `;
                
                // 详细结果
                html += `<div style="margin-top: 20px;"><h5>📋 详细结果：</h5>`;
                results.forEach(result => {
                    const statusIcon = result.hasPermission ? '✅' : '❌';
                    const statusText = result.hasPermission ? '有权限' : '无权限';
                    const statusClass = result.hasPermission ? 'result-success' : 'result-error';
                    
                    html += `
                        <div class="test-result-item ${statusClass}">
                            <span>${scopeConfig[result.scope].icon} ${result.scopeTitle}</span>
                            <span>${statusIcon} ${statusText}</span>
                        </div>
                    `;
                });
                html += `</div>`;
                
                // 汇总说明
                if (successCount === totalCount) {
                    html += `
                        <div style="margin-top: 15px; padding: 15px; background: #d4edda; border-radius: 8px; color: #155724;">
                            <strong>🎉 完美！</strong><br>
                            您拥有所有${totalCount}个范围的通知发布权限，拥有最高级别的系统权限。
                        </div>
                    `;
                } else if (successCount > 0) {
                    html += `
                        <div style="margin-top: 15px; padding: 15px; background: #fff3cd; border-radius: 8px; color: #856404;">
                            <strong>⚖️ 部分权限</strong><br>
                            您拥有${successCount}个范围的权限，${totalCount - successCount}个范围无权限。
                            这符合角色权限设计原则。
                        </div>
                    `;
                } else {
                    html += `
                        <div style="margin-top: 15px; padding: 15px; background: #f8d7da; border-radius: 8px; color: #721c24;">
                            <strong>❌ 无权限</strong><br>
                            您没有任何范围的通知发布权限。请联系管理员检查角色配置。
                        </div>
                    `;
                }
                
                container.innerHTML = html;
                addLog('✅ 全部测试结果已显示', 'success');
                
            } catch (error) {
                addLog(`❌ 显示全部测试结果失败: ${error.message}`, 'error');
            }
        }

        // 显示权限对比
        function showPermissionComparison() {
            let comparison = `
🔍 角色权限对比分析

📊 各角色范围权限分布：

🎩 校长 (PRINCIPAL):
• 权限范围：4个 (SCHOOL_WIDE, DEPARTMENT, CLASS, GRADE)
• 权限级别：最高
• 特殊权限：全校统一管理、紧急通知发布、所有范围审批

👔 教务主任 (ACADEMIC_ADMIN):
• 权限范围：3个 (SCHOOL_WIDE, DEPARTMENT, GRADE)
• 权限级别：高级
• 特殊权限：教务管理、年级统筹、需要校长审批1级通知

👨‍🏫 教师 (TEACHER):
• 权限范围：2个 (DEPARTMENT, CLASS)
• 权限级别：中级
• 特殊权限：教学管理、班级通知、部门协调

👩‍🏫 班主任 (CLASS_TEACHER):
• 权限范围：2个 (CLASS, GRADE)
• 权限级别：中级
• 特殊权限：班级管理、年级活动、学生事务

🎓 学生 (STUDENT):
• 权限范围：1个 (CLASS)
• 权限级别：基础
• 特殊权限：班级内部通知、学生活动组织

📈 权限设计原则：
• 最小权限原则：每个角色拥有最小必要权限
• 层级管理：从校长到学生的权限递减
• 专业分工：不同角色在专业领域有专门权限
• 安全控制：防止权限滥用和越权操作

💡 当前角色对比：
您当前是：${roleAccounts[currentUser.roleCode]?.displayName}
拥有权限：${currentAvailableScopes.length}个范围
权限排名：第${['PRINCIPAL', 'ACADEMIC_ADMIN', 'TEACHER', 'CLASS_TEACHER', 'STUDENT'].indexOf(currentUser.roleCode) + 1}位
            `;
            
            alert(comparison);
            addLog('📊 已显示权限对比分析', 'info');
        }

        // 导出权限矩阵
        function exportPermissionMatrix() {
            try {
                let exportData = '智能通知系统 - 通知范围权限矩阵\n\n';
                exportData += '生成时间：' + new Date().toLocaleString() + '\n';
                exportData += '生成用户：' + (currentUser ? (currentUser.realName || currentUser.username) : '未知') + '\n\n';
                
                exportData += '权限矩阵：\n';
                exportData += '角色\\范围\t全校\t部门\t班级\t年级\n';
                
                Object.keys(SCOPE_PERMISSION_MATRIX).forEach(role => {
                    const permissions = SCOPE_PERMISSION_MATRIX[role];
                    const roleName = roleAccounts[role]?.displayName || role;
                    exportData += roleName + '\t';
                    
                    ['SCHOOL_WIDE', 'DEPARTMENT', 'CLASS', 'GRADE'].forEach(scope => {
                        exportData += (permissions.includes(scope) ? '✓' : '✗') + '\t';
                    });
                    exportData += '\n';
                });
                
                exportData += '\n范围说明：\n';
                Object.keys(scopeConfig).forEach(scope => {
                    const config = scopeConfig[scope];
                    exportData += `${config.title}: ${config.description}\n`;
                });
                
                // 创建下载
                const blob = new Blob([exportData], { type: 'text/plain;charset=utf-8' });
                const url = window.URL.createObjectURL(blob);
                const a = document.createElement('a');
                a.href = url;
                a.download = '智能通知系统-权限矩阵-' + new Date().toISOString().split('T')[0] + '.txt';
                document.body.appendChild(a);
                a.click();
                document.body.removeChild(a);
                window.URL.revokeObjectURL(url);
                
                addLog('✅ 权限矩阵已导出为文本文件', 'success');
                
            } catch (error) {
                addLog(`❌ 导出权限矩阵失败: ${error.message}`, 'error');
            }
        }

        // 显示范围说明
        function showScopeExplanation() {
            const explanation = `
🎯 通知范围详细说明

📋 四个通知范围的定义和用途：

🏫 SCHOOL_WIDE (全校范围)
• 定义：面向全校师生的重要通知
• 适用场景：学校政策、重大活动、紧急通知
• 发布权限：校长、教务主任
• 示例：开学时间调整、重要会议通知、安全提醒

🏢 DEPARTMENT (部门范围)
• 定义：针对特定部门或教研组的通知
• 适用场景：部门工作安排、专业培训、工作会议
• 发布权限：校长、教务主任、教师
• 示例：教研活动安排、部门会议、专业培训

🎓 CLASS (班级范围)
• 定义：针对特定班级学生的通知
• 适用场景：班级事务、课程调整、班级活动
• 发布权限：校长、教师、班主任、学生
• 示例：课表调整、班级活动、作业通知

📚 GRADE (年级范围)
• 定义：针对特定年级所有学生的通知
• 适用场景：年级活动、考试安排、年级管理
• 发布权限：校长、教务主任、班主任
• 示例：年级考试、升学指导、年级活动

⚖️ 权限设计逻辑：
• 管理层面：校长>教务主任>教师>班主任>学生
• 专业分工：不同角色在专业领域有特定权限
• 安全考虑：防止信息误发和权限滥用
• 效率优化：让合适的人在合适的范围发通知

💡 实际应用场景：
• 紧急通知：校长可快速发布全校紧急通知
• 教学管理：教师可向相关班级发布课程调整
• 班级管理：班主任可向班级和年级发布管理通知
• 学生活动：学生可向班级发布活动组织通知

当前您的角色权限已在左侧权限矩阵中高亮显示。
            `;
            
            alert(explanation);
            addLog('📖 已显示范围说明', 'info');
        }

        // HTML转义函数 - 防止XSS攻击
        function escapeHtml(unsafe) {
            if (typeof unsafe !== 'string') {
                unsafe = String(unsafe);
            }
            return unsafe
                .replace(/&/g, "&amp;")
                .replace(/</g, "&lt;")
                .replace(/>/g, "&gt;")
                .replace(/"/g, "&quot;")
                .replace(/'/g, "&#039;");
        }

        // 输入验证函数 - 验证和清理用户输入
        function validateAndSanitizeInput(input, maxLength = 1000) {
            if (typeof input !== 'string') {
                return '';
            }
            
            // 长度限制
            if (input.length > maxLength) {
                input = input.substring(0, maxLength);
            }
            
            // 移除潜在危险字符
            input = input.replace(/<script[^>]*>.*?<\/script>/gi, '');
            input = input.replace(/<iframe[^>]*>.*?<\/iframe>/gi, '');
            input = input.replace(/javascript:/gi, '');
            input = input.replace(/on\w+\s*=/gi, '');
            
            return input.trim();
        }

        // 安全创建DOM元素函数
        function createSafeElement(tagName, textContent = '', className = '', attributes = {}) {
            const element = document.createElement(tagName);
            
            if (textContent) {
                element.textContent = validateAndSanitizeInput(textContent);
            }
            
            if (className) {
                element.className = validateAndSanitizeInput(className);
            }
            
            // 安全设置属性
            Object.keys(attributes).forEach(key => {
                const value = validateAndSanitizeInput(attributes[key]);
                element.setAttribute(key, value);
            });
            
            return element;
        }

        // =======================================================
        // ================== 🧪 权限边界测试系统 =================
        // =======================================================
        
        // 初始化权限边界测试系统
        function initializeBoundaryTestingSystem() {
            try {
                addLog('🧪 初始化权限边界测试系统...', 'info');
                
                // 渲染测试场景选项
                renderTestScenarios();
                
                // 重置测试状态
                resetBoundaryTestState();
                
                addLog('✅ 权限边界测试系统初始化完成', 'success');
            } catch (error) {
                addLog(`❌ 初始化权限边界测试系统失败: ${error.message}`, 'error');
            }
        }
        
        // 显示权限边界测试系统
        function showBoundaryTestingSystem() {
            if (!currentUser) {
                showErrorAlert('请先登录并选择角色');
                return;
            }
            
            const section = document.getElementById('boundaryTestingSection');
            if (section) {
                section.style.display = 'block';
                section.scrollIntoView({ behavior: 'smooth', block: 'start' });
                
                // 重新渲染测试场景（基于当前角色）
                renderTestScenarios();
                updateTestSelectionInfo();
                
                addLog('🎯 权限边界测试系统已打开', 'info');
            }
        }
        
        // 渲染测试场景选项
        function renderTestScenarios() {
            const container = document.getElementById('testScenarioGrid');
            if (!container) return;
            
            try {
                container.innerHTML = ''; // 清空现有内容
                
                Object.keys(BOUNDARY_TEST_SCENARIOS).forEach(scenarioKey => {
                    const scenario = BOUNDARY_TEST_SCENARIOS[scenarioKey];
                    const isSelected = selectedTestScenarios.includes(scenarioKey);
                    
                    // 计算该场景的测试数量
                    const testCount = currentUser ? 
                        scenario.generateTests(currentUser.roleCode).length : 0;
                    
                    // 创建测试场景卡片
                    const cardDiv = createSafeElement('div', '', `test-scenario-card ${isSelected ? 'selected' : ''}`);
                    cardDiv.setAttribute('data-scenario', scenarioKey);
                    cardDiv.onclick = () => toggleTestScenario(scenarioKey);
                    
                    // 场景标题
                    const headerDiv = createSafeElement('div', '', 'test-scenario-header');
                    const iconDiv = createSafeElement('div', scenario.icon, 'test-scenario-icon');
                    const titleDiv = createSafeElement('div', scenario.title, 'test-scenario-title');
                    
                    headerDiv.appendChild(iconDiv);
                    headerDiv.appendChild(titleDiv);
                    
                    // 场景描述
                    const descDiv = createSafeElement('div', scenario.description, 'test-scenario-desc');
                    
                    // 场景统计
                    const statsDiv = createSafeElement('div', '', 'test-scenario-stats');
                    const countStat = createSafeElement('div', `${testCount} 个测试`, 'test-stat');
                    const typeStat = createSafeElement('div', scenarioKey.toUpperCase(), 'test-stat');
                    
                    statsDiv.appendChild(countStat);
                    statsDiv.appendChild(typeStat);
                    
                    // 组装卡片
                    cardDiv.appendChild(headerDiv);
                    cardDiv.appendChild(descDiv);
                    cardDiv.appendChild(statsDiv);
                    
                    // 选中标记
                    if (isSelected) {
                        const checkDiv = createSafeElement('div', '✓');
                        checkDiv.style.cssText = 'position: absolute; top: 10px; right: 10px; background: rgba(255,255,255,0.8); color: #28a745; width: 24px; height: 24px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 0.9rem; font-weight: 600;';
                        cardDiv.appendChild(checkDiv);
                    }
                    
                    container.appendChild(cardDiv);
                });
                
                addLog(`✅ 已渲染 ${Object.keys(BOUNDARY_TEST_SCENARIOS).length} 个测试场景`, 'success');
                
            } catch (error) {
                addLog(`❌ 渲染测试场景失败: ${error.message}`, 'error');
            }
        }
        
        // 切换测试模式
        function switchTestMode(mode) {
            testingMode = mode;
            
            // 更新模式按钮状态
            document.querySelectorAll('.test-mode-btn').forEach(btn => {
                btn.classList.remove('active');
            });
            
            const modeBtn = {
                'single': 'singleTestMode',
                'batch': 'batchTestMode', 
                'pressure': 'pressureTestMode'
            };
            
            if (modeBtn[mode]) {
                document.getElementById(modeBtn[mode]).classList.add('active');
            }
            
            // 更新副标题
            const subtitle = document.getElementById('testingSubtitle');
            if (subtitle) {
                const modeText = {
                    'single': '单项精确测试模式',
                    'batch': '批量综合测试模式',
                    'pressure': '高并发压力测试模式'
                };
                subtitle.textContent = modeText[mode] || '智能权限验证与分析平台';
            }
            
            addLog(`🔧 切换到${mode}测试模式`, 'info');
            updateTestSelectionInfo();
        }
        
        // 切换测试场景选择
        function toggleTestScenario(scenarioKey) {
            const index = selectedTestScenarios.indexOf(scenarioKey);
            
            if (index === -1) {
                selectedTestScenarios.push(scenarioKey);
                addLog(`✅ 选中测试场景: ${BOUNDARY_TEST_SCENARIOS[scenarioKey].title}`, 'success');
            } else {
                selectedTestScenarios.splice(index, 1);
                addLog(`⭕ 取消选中测试场景: ${BOUNDARY_TEST_SCENARIOS[scenarioKey].title}`, 'info');
            }
            
            // 重新渲染场景
            renderTestScenarios();
            updateTestSelectionInfo();
            updateStartTestButtonState();
        }
        
        // 更新测试选择信息
        function updateTestSelectionInfo() {
            const infoElement = document.getElementById('testSelectionInfo');
            if (!infoElement) return;
            
            try {
                if (selectedTestScenarios.length === 0) {
                    infoElement.textContent = '请选择测试场景';
                    infoElement.style.color = 'rgba(255,255,255,0.6)';
                } else {
                    let totalTests = 0;
                    if (currentUser) {
                        selectedTestScenarios.forEach(scenarioKey => {
                            const scenario = BOUNDARY_TEST_SCENARIOS[scenarioKey];
                            if (scenario && scenario.generateTests) {
                                totalTests += scenario.generateTests(currentUser.roleCode).length;
                            }
                        });
                    }
                    
                    infoElement.textContent = `已选择 ${selectedTestScenarios.length} 个场景，共 ${totalTests} 个测试项`;
                    infoElement.style.color = 'rgba(255,255,255,0.9)';
                }
            } catch (error) {
                addLog(`❌ 更新测试选择信息失败: ${error.message}`, 'error');
            }
        }
        
        // 更新开始测试按钮状态
        function updateStartTestButtonState() {
            const startBtn = document.getElementById('startBoundaryTest');
            if (startBtn) {
                const canStart = selectedTestScenarios.length > 0 && !isTestingInProgress && currentUser;
                startBtn.disabled = !canStart;
                
                if (isTestingInProgress) {
                    startBtn.textContent = '🔄 测试执行中...';
                } else if (selectedTestScenarios.length === 0) {
                    startBtn.textContent = '🚀 开始边界测试';
                } else {
                    startBtn.textContent = `🚀 开始测试 (${selectedTestScenarios.length} 场景)`;
                }
            }
        }
        
        // 开始边界测试
        async function startBoundaryTest() {
            if (!currentUser || !currentToken) {
                showErrorAlert('请先登录并完成认证');
                return;
            }
            
            if (selectedTestScenarios.length === 0) {
                showErrorAlert('请至少选择一个测试场景');
                return;
            }
            
            try {
                // 初始化测试状态
                isTestingInProgress = true;
                boundaryTestResults = [];
                
                // 生成测试用例
                const allTests = [];
                selectedTestScenarios.forEach(scenarioKey => {
                    const scenario = BOUNDARY_TEST_SCENARIOS[scenarioKey];
                    if (scenario && scenario.generateTests) {
                        const tests = scenario.generateTests(currentUser.roleCode);
                        tests.forEach(test => {
                            test.scenarioKey = scenarioKey;
                            test.id = `${scenarioKey}_${test.role}_${test.scope}_${test.level}_${Date.now()}_${Math.random()}`;
                            allTests.push(test);
                        });
                    }
                });
                
                // 更新统计信息
                testExecutionStats = {
                    total: allTests.length,
                    completed: 0,
                    passed: 0,
                    failed: 0,
                    errors: 0,
                    startTime: Date.now(),
                    endTime: null,
                    avgResponseTime: 0,
                    responseTimes: []
                };
                
                addLog(`🚀 开始权限边界测试: ${testExecutionStats.total} 个测试项`, 'info');
                addLog(`📋 测试场景: ${selectedTestScenarios.map(key => BOUNDARY_TEST_SCENARIOS[key].title).join('、')}`, 'info');
                addLog(`👤 测试角色: ${roleAccounts[currentUser.roleCode]?.displayName}`, 'info');
                
                // 显示进度容器和实时结果容器
                showTestProgressContainer();
                showRealtimeResults();
                updateStartTestButtonState();
                
                // 根据测试模式执行测试
                if (testingMode === 'pressure') {
                    await executePressureTest(allTests);
                } else {
                    await executeSequentialTest(allTests);
                }
                
                // 完成测试
                testExecutionStats.endTime = Date.now();
                const duration = testExecutionStats.endTime - testExecutionStats.startTime;
                testExecutionStats.avgResponseTime = testExecutionStats.responseTimes.length > 0 ? 
                    testExecutionStats.responseTimes.reduce((a, b) => a + b, 0) / testExecutionStats.responseTimes.length : 0;
                
                addLog(`✅ 权限边界测试完成: ${testExecutionStats.passed}/${testExecutionStats.total} 通过`, 'success');
                addLog(`⏱️ 总耗时: ${duration}ms, 平均响应: ${Math.round(testExecutionStats.avgResponseTime)}ms`, 'info');
                
                // 生成并显示测试报告
                generateTestReport();
                
            } catch (error) {
                addLog(`❌ 权限边界测试执行失败: ${error.message}`, 'error');
                showErrorAlert(`测试执行失败：${error.message}`);
            } finally {
                isTestingInProgress = false;
                updateStartTestButtonState();
            }
        }
        
        // 执行顺序测试
        async function executeSequentialTest(tests) {
            addLog(`🔄 开始顺序执行 ${tests.length} 个测试...`, 'info');
            
            for (let i = 0; i < tests.length; i++) {
                const test = tests[i];
                
                try {
                    const startTime = Date.now();
                    const result = await executeSingleBoundaryTest(test);
                    const responseTime = Date.now() - startTime;
                    
                    // 更新统计
                    testExecutionStats.completed++;
                    testExecutionStats.responseTimes.push(responseTime);
                    
                    if (result.success) {
                        testExecutionStats.passed++;
                    } else if (result.error) {
                        testExecutionStats.errors++;
                    } else {
                        testExecutionStats.failed++;
                    }
                    
                    // 保存结果
                    boundaryTestResults.push({
                        ...result,
                        testId: test.id,
                        responseTime: responseTime,
                        timestamp: Date.now()
                    });
                    
                    // 更新UI
                    updateTestProgress();
                    addRealtimeResult(result, responseTime);
                    
                    // 添加延迟避免请求过快
                    if (testingMode !== 'pressure') {
                        await new Promise(resolve => setTimeout(resolve, 100));
                    }
                    
                } catch (error) {
                    testExecutionStats.completed++;
                    testExecutionStats.errors++;
                    
                    const errorResult = {
                        test: test,
                        success: false,
                        error: true,
                        message: error.message,
                        apiResult: false
                    };
                    
                    boundaryTestResults.push({
                        ...errorResult,
                        testId: test.id,
                        responseTime: 0,
                        timestamp: Date.now()
                    });
                    
                    updateTestProgress();
                    addRealtimeResult(errorResult, 0);
                }
            }
        }
        
        // 执行压力测试
        async function executePressureTest(tests) {
            addLog(`⚡ 开始高并发压力测试 ${tests.length} 个请求...`, 'info');
            
            // 分批并发执行
            const batchSize = 5; // 每批5个并发请求
            const batches = [];
            
            for (let i = 0; i < tests.length; i += batchSize) {
                batches.push(tests.slice(i, i + batchSize));
            }
            
            for (const batch of batches) {
                const promises = batch.map(async (test) => {
                    try {
                        const startTime = Date.now();
                        const result = await executeSingleBoundaryTest(test);
                        const responseTime = Date.now() - startTime;
                        
                        // 更新统计
                        testExecutionStats.completed++;
                        testExecutionStats.responseTimes.push(responseTime);
                        
                        if (result.success) {
                            testExecutionStats.passed++;
                        } else if (result.error) {
                            testExecutionStats.errors++;
                        } else {
                            testExecutionStats.failed++;
                        }
                        
                        // 保存结果
                        boundaryTestResults.push({
                            ...result,
                            testId: test.id,
                            responseTime: responseTime,
                            timestamp: Date.now()
                        });
                        
                        return { result, responseTime };
                    } catch (error) {
                        testExecutionStats.completed++;
                        testExecutionStats.errors++;
                        
                        const errorResult = {
                            test: test,
                            success: false,
                            error: true,
                            message: error.message,
                            apiResult: false
                        };
                        
                        boundaryTestResults.push({
                            ...errorResult,
                            testId: test.id,
                            responseTime: 0,
                            timestamp: Date.now()
                        });
                        
                        return { result: errorResult, responseTime: 0 };
                    }
                });
                
                // 等待当前批次完成
                const batchResults = await Promise.all(promises);
                
                // 更新UI
                updateTestProgress();
                batchResults.forEach(({ result, responseTime }) => {
                    addRealtimeResult(result, responseTime);
                });
                
                // 批次间稍作延迟
                await new Promise(resolve => setTimeout(resolve, 50));
            }
        }
        
        // 执行单个边界测试
        async function executeSingleBoundaryTest(test) {
            try {
                const cleanToken = currentToken.startsWith('Bearer ') ? currentToken.substring(7) : currentToken;
                
                // 构建测试请求
                const testRequest = {
                    targetScope: test.scope,
                    testType: 'BOUNDARY_PERMISSION_TEST',
                    roleCode: test.role,
                    notificationLevel: test.level,
                    expectedResult: test.expected,
                    testScenario: test.type,
                    userInfo: {
                        name: currentUser.realName || currentUser.username,
                        roleCode: currentUser.roleCode,
                        employeeId: currentUser.employeeId || currentUser.username
                    },
                    testMetadata: {
                        testId: test.id,
                        testTime: new Date().toISOString(),
                        description: test.description,
                        scenario: test.scenarioKey
                    }
                };
                
                const response = await fetch(`${API_BASE}/admin-api/test/notification/api/scope-test`, {
                    method: 'POST',
                    headers: {
                        'Authorization': `Bearer ${cleanToken}`,
                        'tenant-id': '1',
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify(testRequest)
                });
                
                if (response.ok) {
                    const result = await response.json();
                    if (result.code === 0 && result.data) {
                        const apiResult = result.data;
                        const actualResult = determineActualResult(apiResult);
                        const success = compareTestResults(test.expected, actualResult);
                        
                        return {
                            test: test,
                            success: success,
                            expected: test.expected,
                            actual: actualResult,
                            apiData: apiResult,
                            apiResult: true,
                            message: success ? '测试通过' : `期望${test.expected}，实际${actualResult}`
                        };
                    } else {
                        throw new Error(result.msg || result.message || 'API返回错误');
                    }
                } else {
                    throw new Error(`HTTP ${response.status}: ${response.statusText}`);
                }
                
            } catch (error) {
                // 使用本地配置进行验证
                const localResult = verifyPermissionLocally(test);
                const success = compareTestResults(test.expected, localResult);
                
                return {
                    test: test,
                    success: success,
                    expected: test.expected,
                    actual: localResult,
                    apiResult: false,
                    error: true,
                    message: error.message,
                    fallbackMode: true
                };
            }
        }
        
        // 确定实际测试结果
        function determineActualResult(apiData) {
            if (apiData.hasPermission === true) {
                return 'ALLOWED';
            } else if (apiData.hasPermission === false) {
                return 'DENIED';
            } else if (apiData.needsApproval === true || apiData.pendingApproval === true) {
                return 'PENDING_APPROVAL';
            } else {
                return 'ERROR';
            }
        }
        
        // 本地权限验证
        function verifyPermissionLocally(test) {
            try {
                const rolePermissions = ENHANCED_PERMISSION_MATRIX[test.role];
                if (!rolePermissions) {
                    return 'ERROR';
                }
                
                const scopePermissions = rolePermissions[test.scope];
                if (!scopePermissions || scopePermissions.length === 0) {
                    return 'DENIED';
                }
                
                if (scopePermissions.includes(test.level)) {
                    return 'ALLOWED';
                } else if (test.role === 'ACADEMIC_ADMIN' && test.scope === 'SCHOOL_WIDE' && test.level === 1) {
                    // 教务主任1级全校通知需要审批
                    return 'PENDING_APPROVAL';
                } else {
                    return 'DENIED';
                }
            } catch (error) {
                return 'ERROR';
            }
        }
        
        // 比较测试结果
        function compareTestResults(expected, actual) {
            return expected === actual;
        }
        
        // 显示测试进度容器
        function showTestProgressContainer() {
            const container = document.getElementById('testProgressContainer');
            if (container) {
                container.style.display = 'block';
                updateTestProgress();
            }
        }
        
        // 更新测试进度
        function updateTestProgress() {
            const progressText = document.getElementById('testProgressText');
            const progressFill = document.getElementById('testProgressFill');
            const statsContainer = document.getElementById('testProgressStats');
            
            if (progressText) {
                progressText.textContent = `${testExecutionStats.completed}/${testExecutionStats.total}`;
            }
            
            if (progressFill) {
                const percentage = testExecutionStats.total > 0 ? 
                    (testExecutionStats.completed / testExecutionStats.total) * 100 : 0;
                progressFill.style.width = `${percentage}%`;
                progressFill.textContent = `${Math.round(percentage)}%`;
            }
            
            if (statsContainer) {
                statsContainer.innerHTML = '';
                
                const stats = [
                    { label: '总计', value: testExecutionStats.total, color: '#667eea' },
                    { label: '已完成', value: testExecutionStats.completed, color: '#17a2b8' },
                    { label: '通过', value: testExecutionStats.passed, color: '#28a745' },
                    { label: '失败', value: testExecutionStats.failed, color: '#ffc107' },
                    { label: '错误', value: testExecutionStats.errors, color: '#dc3545' }
                ];
                
                stats.forEach(stat => {
                    const statDiv = createSafeElement('div', '', 'progress-stat');
                    statDiv.style.borderLeftColor = stat.color;
                    
                    const valueDiv = createSafeElement('div', stat.value.toString(), 'progress-stat-value');
                    const labelDiv = createSafeElement('div', stat.label, 'progress-stat-label');
                    
                    statDiv.appendChild(valueDiv);
                    statDiv.appendChild(labelDiv);
                    statsContainer.appendChild(statDiv);
                });
            }
        }
        
        // 显示实时结果
        function showRealtimeResults() {
            const container = document.getElementById('realtimeResults');
            if (container) {
                container.style.display = 'block';
                
                // 清空现有结果
                const resultsContainer = document.getElementById('resultsContainer');
                if (resultsContainer) {
                    resultsContainer.innerHTML = '';
                }
                
                updateResultsCount();
            }
        }
        
        // 添加实时结果项
        function addRealtimeResult(result, responseTime) {
            const resultsContainer = document.getElementById('resultsContainer');
            if (!resultsContainer) return;
            
            try {
                const resultDiv = createSafeElement('div', '', 'result-item');
                
                // 左侧信息
                const leftDiv = createSafeElement('div', '', 'result-left');
                
                // 结果图标
                const iconDiv = createSafeElement('div', '', 'result-icon');
                if (result.success) {
                    iconDiv.classList.add('success');
                    iconDiv.textContent = '✓';
                } else if (result.error) {
                    iconDiv.classList.add('failure');
                    iconDiv.textContent = '!';
                } else {
                    iconDiv.classList.add('failure');
                    iconDiv.textContent = '✗';
                }
                
                // 结果信息
                const infoDiv = createSafeElement('div', '', 'result-info');
                const titleDiv = createSafeElement('div', result.test.description, 'result-title');
                const descDiv = createSafeElement('div', 
                    `${scopeConfig[result.test.scope]?.title || result.test.scope} - ${NOTIFICATION_LEVELS[result.test.level]?.name || result.test.level}`, 
                    'result-desc');
                
                infoDiv.appendChild(titleDiv);
                infoDiv.appendChild(descDiv);
                
                leftDiv.appendChild(iconDiv);
                leftDiv.appendChild(infoDiv);
                
                // 右侧状态
                const rightDiv = createSafeElement('div', '', 'result-right');
                
                const timeDiv = createSafeElement('div', `${responseTime}ms`, 'result-time');
                
                const statusDiv = createSafeElement('div', '', 'result-status');
                if (result.success) {
                    statusDiv.classList.add('success');
                    statusDiv.textContent = '通过';
                } else if (result.error) {
                    statusDiv.classList.add('failure');
                    statusDiv.textContent = '错误';
                } else {
                    statusDiv.classList.add('failure');
                    statusDiv.textContent = '失败';
                }
                
                rightDiv.appendChild(timeDiv);
                rightDiv.appendChild(statusDiv);
                
                // 组装结果项
                resultDiv.appendChild(leftDiv);
                resultDiv.appendChild(rightDiv);
                
                // 添加到容器顶部
                resultsContainer.insertBefore(resultDiv, resultsContainer.firstChild);
                
                // 更新结果计数
                updateResultsCount();
                
            } catch (error) {
                addLog(`❌ 添加实时结果失败: ${error.message}`, 'error');
            }
        }
        
        // 更新结果计数
        function updateResultsCount() {
            const countElement = document.getElementById('resultsCount');
            if (countElement) {
                countElement.textContent = `${boundaryTestResults.length} 项结果`;
            }
        }
        
        // 重置边界测试
        function resetBoundaryTest() {
            selectedTestScenarios = [];
            resetBoundaryTestState();
            renderTestScenarios();
            updateTestSelectionInfo();
            updateStartTestButtonState();
            
            // 隐藏相关容器
            const progressContainer = document.getElementById('testProgressContainer');
            const resultsContainer = document.getElementById('realtimeResults');
            const reportContainer = document.getElementById('testReport');
            
            if (progressContainer) progressContainer.style.display = 'none';
            if (resultsContainer) resultsContainer.style.display = 'none';
            if (reportContainer) reportContainer.style.display = 'none';
            
            addLog('🔄 已重置边界测试系统', 'info');
        }
        
        // 重置边界测试状态
        function resetBoundaryTestState() {
            boundaryTestResults = [];
            testExecutionStats = {
                total: 0,
                completed: 0,
                passed: 0,
                failed: 0,
                errors: 0,
                startTime: null,
                endTime: null,
                avgResponseTime: 0,
                responseTimes: []
            };
            isTestingInProgress = false;
        }
        
        // 添加日志记录函数 - XSS安全版本
        function addLog(message, type = 'info') {
            try {
                const logElement = document.getElementById('testLog');
                
                if (!logElement) {
                    console.log(`[${type.toUpperCase()}] ${message}`);
                    return;
                }
                
                const timestamp = new Date().toLocaleTimeString();
                const icons = {
                    'info': 'ℹ️',
                    'success': '✅', 
                    'error': '❌',
                    'warning': '⚠️'
                };
                
                const colors = {
                    'info': '#17a2b8',
                    'success': '#28a745',
                    'error': '#dc3545', 
                    'warning': '#ffc107'
                };
                
                // 使用安全的DOM操作
                const logEntry = createSafeElement('div');
                logEntry.style.marginBottom = '8px';
                logEntry.style.color = colors[type] || colors.info;
                
                const timestampSpan = createSafeElement('span', `[${timestamp}] `);
                const iconSpan = createSafeElement('span', `${icons[type] || icons.info} `);
                const messageSpan = createSafeElement('span', validateAndSanitizeInput(message));
                
                logEntry.appendChild(timestampSpan);
                logEntry.appendChild(iconSpan);
                logEntry.appendChild(messageSpan);
                
                logElement.appendChild(logEntry);
                logElement.scrollTop = logElement.scrollHeight;
                
                console.log(`[${type.toUpperCase()}] ${message}`);
                
                if (type === 'error') {
                    console.error(`Phase6 Error: ${message}`);
                }
                
            } catch (logError) {
                console.error('日志函数错误:', logError);
                console.log(`[${type.toUpperCase()}] ${message}`);
            }
        }

        // 生成测试报告
        function generateTestReport() {
            try {
                const reportContainer = document.getElementById('testReport');
                if (!reportContainer) return;
                
                reportContainer.style.display = 'block';
                reportContainer.scrollIntoView({ behavior: 'smooth', block: 'start' });
                
                // 生成报告摘要
                generateReportSummary();
                
                // 生成覆盖范围详情
                generateCoverageDetails();
                
                // 生成API vs 本地配置对比
                generateComparisonTable();
                
                // 生成性能统计
                generatePerformanceStats();
                
                // 生成异常发现
                generateAnomalyDetails();
                
                addLog('📊 测试报告已生成', 'success');
                
            } catch (error) {
                addLog(`❌ 生成测试报告失败: ${error.message}`, 'error');
            }
        }
        
        // 生成报告摘要
        function generateReportSummary() {
            const summaryContainer = document.getElementById('reportSummary');
            if (!summaryContainer) return;
            
            try {
                summaryContainer.innerHTML = '';
                
                const duration = testExecutionStats.endTime - testExecutionStats.startTime;
                const successRate = testExecutionStats.total > 0 ? 
                    (testExecutionStats.passed / testExecutionStats.total * 100).toFixed(1) : 0;
                
                const summaryData = [
                    { label: '测试总数', value: testExecutionStats.total, unit: '项' },
                    { label: '成功率', value: successRate, unit: '%' },
                    { label: '总耗时', value: Math.round(duration), unit: 'ms' },
                    { label: '平均响应', value: Math.round(testExecutionStats.avgResponseTime), unit: 'ms' },
                    { label: '通过数', value: testExecutionStats.passed, unit: '项' },
                    { label: '失败数', value: testExecutionStats.failed, unit: '项' },
                    { label: '错误数', value: testExecutionStats.errors, unit: '项' },
                    { label: 'API成功率', value: calculateApiSuccessRate(), unit: '%' }
                ];
                
                summaryData.forEach(item => {
                    const cardDiv = createSafeElement('div', '', 'summary-card');
                    const valueDiv = createSafeElement('div', `${item.value}${item.unit}`, 'summary-value');
                    const labelDiv = createSafeElement('div', item.label, 'summary-label');
                    
                    cardDiv.appendChild(valueDiv);
                    cardDiv.appendChild(labelDiv);
                    summaryContainer.appendChild(cardDiv);
                });
                
            } catch (error) {
                addLog(`❌ 生成报告摘要失败: ${error.message}`, 'error');
            }
        }
        
        // 计算API成功率
        function calculateApiSuccessRate() {
            if (boundaryTestResults.length === 0) return 0;
            
            const apiResults = boundaryTestResults.filter(result => result.apiResult === true);
            return (apiResults.length / boundaryTestResults.length * 100).toFixed(1);
        }
        
        // 生成覆盖范围详情
        function generateCoverageDetails() {
            const container = document.getElementById('coverageDetails');
            if (!container) return;
            
            try {
                const scenarioStats = {};
                const roleStats = {};
                
                boundaryTestResults.forEach(result => {
                    const test = result.test;
                    
                    // 统计场景覆盖
                    if (!scenarioStats[test.scenarioKey]) {
                        scenarioStats[test.scenarioKey] = { total: 0, passed: 0 };
                    }
                    scenarioStats[test.scenarioKey].total++;
                    if (result.success) scenarioStats[test.scenarioKey].passed++;
                    
                    // 统计角色覆盖
                    if (!roleStats[test.role]) {
                        roleStats[test.role] = { total: 0, passed: 0 };
                    }
                    roleStats[test.role].total++;
                    if (result.success) roleStats[test.role].passed++;
                });
                
                let coverageHTML = `
                    <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 20px;">
                        <div>
                            <h6>🎯 场景覆盖统计：</h6>
                            <ul style="list-style: none; padding: 0; margin: 10px 0;">
                `;
                
                Object.keys(scenarioStats).forEach(scenario => {
                    const stat = scenarioStats[scenario];
                    const rate = ((stat.passed / stat.total) * 100).toFixed(1);
                    const title = BOUNDARY_TEST_SCENARIOS[scenario]?.title || scenario;
                    coverageHTML += `
                        <li style="margin: 5px 0; display: flex; justify-content: space-between;">
                            <span>${BOUNDARY_TEST_SCENARIOS[scenario]?.icon} ${title}</span>
                            <span>${stat.passed}/${stat.total} (${rate}%)</span>
                        </li>
                    `;
                });
                
                coverageHTML += `
                            </ul>
                        </div>
                        <div>
                            <h6>📋 角色覆盖统计：</h6>
                            <ul style="list-style: none; padding: 0; margin: 10px 0;">
                `;
                
                Object.keys(roleStats).forEach(role => {
                    const stat = roleStats[role];
                    const rate = ((stat.passed / stat.total) * 100).toFixed(1);
                    const title = roleAccounts[role]?.displayName || role;
                    coverageHTML += `
                        <li style="margin: 5px 0; display: flex; justify-content: space-between;">
                            <span>${getRoleIcon(role)} ${title}</span>
                            <span>${stat.passed}/${stat.total} (${rate}%)</span>
                        </li>
                    `;
                });
                
                coverageHTML += `
                            </ul>
                        </div>
                    </div>
                `;
                
                container.innerHTML = coverageHTML;
                
            } catch (error) {
                addLog(`❌ 生成覆盖范围详情失败: ${error.message}`, 'error');
            }
        }
        
        // 生成对比表格
        function generateComparisonTable() {
            const table = document.getElementById('comparisonTable');
            if (!table) return;
            
            try {
                let tableHTML = `
                    <thead>
                        <tr>
                            <th>测试项</th>
                            <th>期望结果</th>
                            <th>API结果</th>
                            <th>本地配置</th>
                            <th>一致性</th>
                            <th>响应时间</th>
                        </tr>
                    </thead>
                    <tbody>
                `;
                
                boundaryTestResults.slice(0, 20).forEach(result => { // 只显示前20项
                    const test = result.test;
                    const apiResult = result.apiResult ? result.actual : 'N/A';
                    const localResult = verifyPermissionLocally(test);
                    const consistent = result.apiResult && (result.actual === localResult);
                    
                    tableHTML += `
                        <tr>
                            <td style="text-align: left; max-width: 200px; word-break: break-word;">
                                ${scopeConfig[test.scope]?.title}-${NOTIFICATION_LEVELS[test.level]?.name}
                            </td>
                            <td>${translateResult(test.expected)}</td>
                            <td>${result.apiResult ? translateResult(apiResult) : '错误'}</td>
                            <td>${translateResult(localResult)}</td>
                            <td>
                                <div class="comparison-result ${consistent ? 'match' : 'mismatch'}">
                                    ${consistent ? '✓ 一致' : '✗ 不一致'}
                                </div>
                            </td>
                            <td>${result.responseTime}ms</td>
                        </tr>
                    `;
                });
                
                if (boundaryTestResults.length > 20) {
                    tableHTML += `
                        <tr>
                            <td colspan="6" style="text-align: center; opacity: 0.6; font-style: italic;">
                                ...及其余${boundaryTestResults.length - 20}项结果
                            </td>
                        </tr>
                    `;
                }
                
                tableHTML += `</tbody>`;
                table.innerHTML = tableHTML;
                
            } catch (error) {
                addLog(`❌ 生成对比表格失败: ${error.message}`, 'error');
            }
        }
        
        // 翻译结果显示
        function translateResult(result) {
            const translations = {
                'ALLOWED': '允许',
                'DENIED': '拒绝',
                'PENDING_APPROVAL': '待审批',
                'ERROR': '错误'
            };
            return translations[result] || result;
        }
        
        // 生成性能统计
        function generatePerformanceStats() {
            const container = document.getElementById('performanceStats');
            if (!container) return;
            
            try {
                const responseTimes = testExecutionStats.responseTimes;
                const sortedTimes = [...responseTimes].sort((a, b) => a - b);
                
                const p50 = sortedTimes[Math.floor(sortedTimes.length * 0.5)] || 0;
                const p95 = sortedTimes[Math.floor(sortedTimes.length * 0.95)] || 0;
                const maxTime = Math.max(...responseTimes);
                const minTime = Math.min(...responseTimes);
                
                const duration = testExecutionStats.endTime - testExecutionStats.startTime;
                const throughput = testExecutionStats.total > 0 ? 
                    (testExecutionStats.total / duration * 1000).toFixed(2) : 0;
                
                let statsHTML = `
                    <div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 15px;">
                        <div style="background: #f8f9fa; padding: 15px; border-radius: 8px; text-align: center;">
                            <div style="font-size: 1.2rem; font-weight: 600; color: #333;">${Math.round(testExecutionStats.avgResponseTime)}ms</div>
                            <div style="font-size: 0.8rem; color: #666;">平均响应时间</div>
                        </div>
                        <div style="background: #f8f9fa; padding: 15px; border-radius: 8px; text-align: center;">
                            <div style="font-size: 1.2rem; font-weight: 600; color: #333;">${p50}ms</div>
                            <div style="font-size: 0.8rem; color: #666;">P50响应时间</div>
                        </div>
                        <div style="background: #f8f9fa; padding: 15px; border-radius: 8px; text-align: center;">
                            <div style="font-size: 1.2rem; font-weight: 600; color: #333;">${p95}ms</div>
                            <div style="font-size: 0.8rem; color: #666;">P95响应时间</div>
                        </div>
                        <div style="background: #f8f9fa; padding: 15px; border-radius: 8px; text-align: center;">
                            <div style="font-size: 1.2rem; font-weight: 600; color: #333;">${maxTime}ms</div>
                            <div style="font-size: 0.8rem; color: #666;">最大响应时间</div>
                        </div>
                        <div style="background: #f8f9fa; padding: 15px; border-radius: 8px; text-align: center;">
                            <div style="font-size: 1.2rem; font-weight: 600; color: #333;">${throughput}</div>
                            <div style="font-size: 0.8rem; color: #666;">吞吐率(req/s)</div>
                        </div>
                    </div>
                `;
                
                container.innerHTML = statsHTML;
                
            } catch (error) {
                addLog(`❌ 生成性能统计失败: ${error.message}`, 'error');
            }
        }
        
        // 生成异常发现
        function generateAnomalyDetails() {
            const container = document.getElementById('anomalyDetails');
            if (!container) return;
            
            try {
                const anomalies = [];
                
                // 检测API vs 本地结果不一致
                boundaryTestResults.forEach(result => {
                    if (result.apiResult) {
                        const localResult = verifyPermissionLocally(result.test);
                        if (result.actual !== localResult) {
                            anomalies.push({
                                type: 'inconsistency',
                                description: `API结果(${result.actual})与本地配置(${localResult})不一致`,
                                test: result.test,
                                severity: 'warning'
                            });
                        }
                    }
                });
                
                // 检测响应时间异常
                const avgResponseTime = testExecutionStats.avgResponseTime;
                boundaryTestResults.forEach(result => {
                    if (result.responseTime > avgResponseTime * 3) {
                        anomalies.push({
                            type: 'slow_response',
                            description: `响应时间过慢: ${result.responseTime}ms (超过平均的3倍)`,
                            test: result.test,
                            severity: 'info'
                        });
                    }
                });
                
                // 检测API错误率
                const apiErrorRate = (testExecutionStats.errors / testExecutionStats.total * 100).toFixed(1);
                if (apiErrorRate > 10) {
                    anomalies.push({
                        type: 'high_error_rate',
                        description: `API错误率过高: ${apiErrorRate}%`,
                        severity: 'error'
                    });
                }
                
                let anomaliesHTML = '';
                
                if (anomalies.length === 0) {
                    anomaliesHTML = `
                        <div style="text-align: center; padding: 20px; color: #28a745;">
                            ✅ 未发现异常情况，所有测试结果符合预期。
                        </div>
                    `;
                } else {
                    anomaliesHTML = '<ul style="list-style: none; padding: 0;">';
                    anomalies.forEach(anomaly => {
                        const icon = {
                            'error': '❌',
                            'warning': '⚠️',
                            'info': 'ℹ️'
                        }[anomaly.severity];
                        
                        anomaliesHTML += `
                            <li style="margin: 10px 0; padding: 10px; background: #f8f9fa; border-left: 4px solid ${anomaly.severity === 'error' ? '#dc3545' : anomaly.severity === 'warning' ? '#ffc107' : '#17a2b8'}; border-radius: 4px;">
                                ${icon} ${anomaly.description}
                            </li>
                        `;
                    });
                    anomaliesHTML += '</ul>';
                }
                
                container.innerHTML = anomaliesHTML;
                
            } catch (error) {
                addLog(`❌ 生成异常发现失败: ${error.message}`, 'error');
            }
        }
        
        // 导出测试报告
        function exportTestReport() {
            try {
                const reportData = {
                    summary: {
                        testTime: new Date().toISOString(),
                        user: currentUser.realName || currentUser.username,
                        role: currentUser.roleCode,
                        testMode: testingMode,
                        scenarios: selectedTestScenarios.map(key => BOUNDARY_TEST_SCENARIOS[key].title),
                        statistics: testExecutionStats
                    },
                    results: boundaryTestResults
                };
                
                const blob = new Blob([JSON.stringify(reportData, null, 2)], { 
                    type: 'application/json;charset=utf-8' 
                });
                const url = window.URL.createObjectURL(blob);
                const a = document.createElement('a');
                a.href = url;
                a.download = `权限边界测试报告-${new Date().toISOString().split('T')[0]}.json`;
                document.body.appendChild(a);
                a.click();
                document.body.removeChild(a);
                window.URL.revokeObjectURL(url);
                
                addLog('📊 测试报告已导出为JSON文件', 'success');
                
            } catch (error) {
                addLog(`❌ 导出测试报告失败: ${error.message}`, 'error');
            }
        }
        
        // 导出CSV报告
        function exportReportAsCSV() {
            try {
                let csvContent = 'data:text/csv;charset=utf-8,';
                csvContent += '测试ID,角色,范围,级别,期望结果,实际结果,测试结果,响应时间,API结果,测试场景\n';
                
                boundaryTestResults.forEach(result => {
                    const test = result.test;
                    const row = [
                        result.testId || 'N/A',
                        roleAccounts[test.role]?.displayName || test.role,
                        scopeConfig[test.scope]?.title || test.scope,
                        NOTIFICATION_LEVELS[test.level]?.name || test.level,
                        translateResult(test.expected),
                        translateResult(result.actual),
                        result.success ? '通过' : '失败',
                        result.responseTime + 'ms',
                        result.apiResult ? '是' : '否',
                        BOUNDARY_TEST_SCENARIOS[test.scenarioKey]?.title || test.scenarioKey
                    ].join(',');
                    csvContent += row + '\n';
                });
                
                const encodedUri = encodeURI(csvContent);
                const a = document.createElement('a');
                a.href = encodedUri;
                a.download = `权限边界测试结果-${new Date().toISOString().split('T')[0]}.csv`;
                document.body.appendChild(a);
                a.click();
                document.body.removeChild(a);
                
                addLog('📄 CSV报告已导出', 'success');
                
            } catch (error) {
                addLog(`❌ 导出CSV报告失败: ${error.message}`, 'error');
            }
        }
        
        // 打印测试报告
        function printTestReport() {
            try {
                const reportContainer = document.getElementById('testReport');
                if (!reportContainer) {
                    showErrorAlert('报告内容不存在');
                    return;
                }
                
                const printWindow = window.open('', '_blank');
                printWindow.document.write(`
                    <!DOCTYPE html>
                    <html>
                    <head>
                        <title>权限边界测试报告</title>
                        <style>
                            body { font-family: Arial, sans-serif; margin: 20px; }
                            .report-header { text-align: center; margin-bottom: 30px; }
                            .summary-card { display: inline-block; margin: 10px; padding: 15px; border: 1px solid #ddd; border-radius: 8px; text-align: center; }
                            .comparison-table { width: 100%; border-collapse: collapse; margin: 20px 0; }
                            .comparison-table th, .comparison-table td { border: 1px solid #ddd; padding: 8px; text-align: center; }
                            .comparison-table th { background: #f5f5f5; }
                            @media print { .no-print { display: none; } }
                        </style>
                    </head>
                    <body>
                        <div class="report-header">
                            <h1>权限边界测试报告</h1>
                            <p>生成时间：${new Date().toLocaleString()}</p>
                            <p>测试用户：${currentUser.realName || currentUser.username} (${roleAccounts[currentUser.roleCode]?.displayName})</p>
                        </div>
                        ${reportContainer.innerHTML}
                    </body>
                    </html>
                `);
                printWindow.document.close();
                printWindow.focus();
                
                setTimeout(() => {
                    printWindow.print();
                    printWindow.close();
                }, 500);
                
                addLog('🖨️ 测试报告已发送至打印机', 'success');
                
            } catch (error) {
                addLog(`❌ 打印测试报告失败: ${error.message}`, 'error');
            }
        }
        
        // ==================== 权限升级演示功能 ====================
        
        // 角色升级路径定义
        const ROLE_UPGRADE_PATH = [
            {
                roleCode: 'STUDENT',
                order: 1,
                displayName: '学生',
                icon: '🎓',
                description: '权限初级：仅能发布班级内日常通知',
                color: '#28a745'
            },
            {
                roleCode: 'CLASS_TEACHER',
                order: 2,
                displayName: '班主任',
                icon: '👨‍🏫',
                description: '权限提升：管理班级和年级通知',
                color: '#17a2b8'
            },
            {
                roleCode: 'TEACHER',
                order: 3,
                displayName: '教师',
                icon: '👩‍🏫',
                description: '权限扩展：负责部门和班级事务',
                color: '#ffc107'
            },
            {
                roleCode: 'ACADEMIC_ADMIN',
                order: 4,
                displayName: '教务主任',
                icon: '👔',
                description: '权限进阶：统筹全校教学管理',
                color: '#fd7e14'
            },
            {
                roleCode: 'PRINCIPAL',
                order: 5,
                displayName: '校长',
                icon: '🎖️',
                description: '权限巅峰：全校全权限管理',
                color: '#dc3545'
            }
        ];
        
        // 权限升级演示状态
        let upgradeDemo = {
            isRunning: false,
            currentStep: 0,
            animationSpeed: 2000,
            comparisonData: {}
        };
        
        // 启动自动权限升级演示
        function startAutomaticUpgradeDemo() {
            if (upgradeDemo.isRunning) {
                addLog('⚠️ 权限升级演示正在运行中...', 'warning');
                return;
            }
            
            upgradeDemo.isRunning = true;
            upgradeDemo.currentStep = 0;
            
            // 显示演示区域
            showUpgradeDemoSection();
            
            addLog('🎬 开始自动权限升级路径演示', 'info');
            addLog('📋 演示路径：学生 → 班主任 → 教师 → 教务主任 → 校长', 'info');
            
            // 渲染升级路径图
            renderUpgradePathVisualization();
            
            // 开始逐步演示
            setTimeout(() => {
                performUpgradeStep();
            }, 1000);
        }
        
        // 显示升级演示区域
        function showUpgradeDemoSection() {
            const section = document.querySelector('[data-view="permission-upgrade"]');
            if (section) {
                // 切换到权限升级视图
                showView('permission-upgrade');
                
                // 滚动到演示区域
                setTimeout(() => {
                    section.scrollIntoView({ behavior: 'smooth', block: 'start' });
                }, 300);
            }
        }
        
        // 渲染升级路径可视化
        function renderUpgradePathVisualization() {
            const container = document.getElementById('hierarchyVisualization');
            if (!container) return;
            
            let visualizationHTML = `
                <div class="upgrade-path-container">
                    <div class="path-header">
                        <div class="path-title">🎯 完整权限升级路径图</div>
                        <div class="path-subtitle">从基础权限到全权限管理的5个层级</div>
                    </div>
                    
                    <div class="path-steps">
            `;
            
            ROLE_UPGRADE_PATH.forEach((role, index) => {
                const permissions = ENHANCED_PERMISSION_MATRIX[role.roleCode] || {};
                const totalPermissions = Object.values(permissions).reduce((sum, levels) => sum + (levels?.length || 0), 0);
                const scopeCount = Object.keys(permissions).filter(scope => permissions[scope]?.length > 0).length;
                
                visualizationHTML += `
                    <div class="path-step" id="pathStep${index}" data-role="${role.roleCode}">
                        <div class="step-header">
                            <div class="step-icon" style="background-color: ${role.color}">
                                ${role.icon}
                            </div>
                            <div class="step-title">${role.displayName}</div>
                        </div>
                        
                        <div class="step-content">
                            <div class="step-description">${role.description}</div>
                            <div class="step-stats">
                                <span class="stat-item">📊 ${totalPermissions}个权限级别</span>
                                <span class="stat-item">🎯 ${scopeCount}个权限范围</span>
                            </div>
                        </div>
                        
                        <div class="step-permissions" id="stepPermissions${index}">
                            <!-- 权限详情将在这里动态显示 -->
                        </div>
                `;
                
                // 添加箭头（除了最后一个）
                if (index < ROLE_UPGRADE_PATH.length - 1) {
                    visualizationHTML += `
                        <div class="upgrade-arrow">
                            <div class="arrow-icon">⬇️</div>
                            <div class="arrow-text">权限升级</div>
                        </div>
                    `;
                }
                
                visualizationHTML += `</div>`;
            });
            
            visualizationHTML += `
                    </div>
                    
                    <div class="path-footer">
                        <div class="upgrade-summary" id="upgradeSummary">
                            点击"🎬 自动演示升级路径"查看详细的权限变化动画
                        </div>
                    </div>
                </div>
            `;
            
            container.innerHTML = visualizationHTML;
            
            // 添加相关CSS样式
            addUpgradeVisualizationStyles();
        }
        
        // 添加升级可视化样式
        function addUpgradeVisualizationStyles() {
            const styleId = 'upgrade-visualization-styles';
            if (document.getElementById(styleId)) return;
            
            const style = document.createElement('style');
            style.id = styleId;
            style.textContent = `
                .upgrade-path-container {
                    background: rgba(255, 255, 255, 0.1);
                    border-radius: 15px;
                    padding: 25px;
                    backdrop-filter: blur(10px);
                    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
                }
                
                .path-header {
                    text-align: center;
                    margin-bottom: 30px;
                }
                
                .path-title {
                    font-size: 1.5rem;
                    font-weight: bold;
                    color: #fff;
                    margin-bottom: 8px;
                    text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
                }
                
                .path-subtitle {
                    color: rgba(255, 255, 255, 0.8);
                    font-size: 1rem;
                }
                
                .path-steps {
                    display: flex;
                    flex-direction: column;
                    gap: 20px;
                    align-items: center;
                }
                
                .path-step {
                    background: rgba(255, 255, 255, 0.15);
                    border-radius: 12px;
                    padding: 20px;
                    width: 100%;
                    max-width: 600px;
                    transition: all 0.3s ease;
                    border: 2px solid transparent;
                }
                
                .path-step.active {
                    border-color: #ffc107;
                    background: rgba(255, 193, 7, 0.2);
                    box-shadow: 0 5px 20px rgba(255, 193, 7, 0.3);
                    transform: scale(1.02);
                }
                
                .step-header {
                    display: flex;
                    align-items: center;
                    gap: 15px;
                    margin-bottom: 15px;
                }
                
                .step-icon {
                    width: 50px;
                    height: 50px;
                    border-radius: 50%;
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    font-size: 1.5rem;
                    color: white;
                    box-shadow: 0 3px 10px rgba(0, 0, 0, 0.2);
                }
                
                .step-title {
                    font-size: 1.3rem;
                    font-weight: bold;
                    color: #fff;
                }
                
                .step-content {
                    margin-left: 65px;
                }
                
                .step-description {
                    color: rgba(255, 255, 255, 0.9);
                    margin-bottom: 12px;
                    line-height: 1.5;
                }
                
                .step-stats {
                    display: flex;
                    gap: 20px;
                    flex-wrap: wrap;
                }
                
                .stat-item {
                    background: rgba(255, 255, 255, 0.1);
                    padding: 5px 12px;
                    border-radius: 20px;
                    color: #fff;
                    font-size: 0.85rem;
                    border: 1px solid rgba(255, 255, 255, 0.2);
                }
                
                .step-permissions {
                    margin-top: 15px;
                    margin-left: 65px;
                    display: none;
                }
                
                .step-permissions.show {
                    display: block;
                    animation: slideDown 0.5s ease-out;
                }
                
                @keyframes slideDown {
                    from {
                        opacity: 0;
                        max-height: 0;
                    }
                    to {
                        opacity: 1;
                        max-height: 300px;
                    }
                }
                
                .upgrade-arrow {
                    text-align: center;
                    margin: 10px 0;
                }
                
                .arrow-icon {
                    font-size: 2rem;
                    animation: bounce 2s infinite;
                }
                
                .arrow-text {
                    color: rgba(255, 255, 255, 0.7);
                    font-size: 0.9rem;
                    margin-top: 5px;
                }
                
                @keyframes bounce {
                    0%, 20%, 50%, 80%, 100% {
                        transform: translateY(0);
                    }
                    40% {
                        transform: translateY(-10px);
                    }
                    60% {
                        transform: translateY(-5px);
                    }
                }
                
                .path-footer {
                    text-align: center;
                    margin-top: 25px;
                    padding-top: 20px;
                    border-top: 1px solid rgba(255, 255, 255, 0.2);
                }
                
                .upgrade-summary {
                    color: rgba(255, 255, 255, 0.8);
                    font-size: 0.95rem;
                    line-height: 1.4;
                }
                
                .permission-detail {
                    background: rgba(0, 0, 0, 0.2);
                    border-radius: 8px;
                    padding: 15px;
                    margin: 10px 0;
                    border-left: 4px solid #ffc107;
                }
                
                .permission-scope {
                    color: #ffc107;
                    font-weight: bold;
                    margin-bottom: 8px;
                }
                
                .permission-levels {
                    display: flex;
                    gap: 8px;
                    flex-wrap: wrap;
                }
                
                .permission-level {
                    background: rgba(40, 167, 69, 0.8);
                    color: white;
                    padding: 4px 8px;
                    border-radius: 12px;
                    font-size: 0.75rem;
                    border: 1px solid rgba(255, 255, 255, 0.3);
                }
            `;
            
            document.head.appendChild(style);
        }
        
        // 执行升级演示步骤
        function performUpgradeStep() {
            if (!upgradeDemo.isRunning || upgradeDemo.currentStep >= ROLE_UPGRADE_PATH.length) {
                finishUpgradeDemo();
                return;
            }
            
            const currentRole = ROLE_UPGRADE_PATH[upgradeDemo.currentStep];
            const stepElement = document.getElementById(`pathStep${upgradeDemo.currentStep}`);
            const permissionsContainer = document.getElementById(`stepPermissions${upgradeDemo.currentStep}`);
            
            // 高亮当前步骤
            document.querySelectorAll('.path-step').forEach(step => {
                step.classList.remove('active');
            });
            
            if (stepElement) {
                stepElement.classList.add('active');
                
                // 滚动到当前步骤
                stepElement.scrollIntoView({ behavior: 'smooth', block: 'center' });
            }
            
            // 显示详细权限信息
            if (permissionsContainer) {
                permissionsContainer.innerHTML = generatePermissionDetails(currentRole.roleCode);
                permissionsContainer.classList.add('show');
            }
            
            // 更新日志
            addLog(`🔄 演示步骤 ${upgradeDemo.currentStep + 1}/5: ${currentRole.displayName} (${currentRole.description})`, 'info');
            
            // 如果有上一个角色，显示权限对比
            if (upgradeDemo.currentStep > 0) {
                const prevRole = ROLE_UPGRADE_PATH[upgradeDemo.currentStep - 1];
                showPermissionComparison(prevRole.roleCode, currentRole.roleCode);
            }
            
            // 更新升级总结
            updateUpgradeSummary();
            
            // 继续下一步
            upgradeDemo.currentStep++;
            setTimeout(() => {
                performUpgradeStep();
            }, upgradeDemo.animationSpeed);
        }
        
        // 生成权限详情
        function generatePermissionDetails(roleCode) {
            const permissions = ENHANCED_PERMISSION_MATRIX[roleCode] || {};
            const scopes = ['SCHOOL_WIDE', 'DEPARTMENT', 'CLASS', 'GRADE'];
            
            let detailHTML = '';
            
            scopes.forEach(scope => {
                const levels = permissions[scope] || [];
                if (levels.length > 0) {
                    const scopeConfig = {
                        'SCHOOL_WIDE': { title: '全校范围', icon: '🏫' },
                        'DEPARTMENT': { title: '部门范围', icon: '🏢' },
                        'CLASS': { title: '班级范围', icon: '🎓' },
                        'GRADE': { title: '年级范围', icon: '📚' }
                    }[scope];
                    
                    detailHTML += `
                        <div class="permission-detail">
                            <div class="permission-scope">
                                ${scopeConfig.icon} ${scopeConfig.title}
                            </div>
                            <div class="permission-levels">
                    `;
                    
                    levels.forEach(level => {
                        const levelName = NOTIFICATION_LEVELS[level]?.name || `${level}级`;
                        detailHTML += `
                            <span class="permission-level">${levelName}</span>
                        `;
                    });
                    
                    detailHTML += `
                            </div>
                        </div>
                    `;
                }
            });
            
            return detailHTML || '<div class="permission-detail">暂无发布权限</div>';
        }
        
        // 显示权限对比
        function showPermissionComparison(fromRole, toRole) {
            const fromPermissions = ENHANCED_PERMISSION_MATRIX[fromRole] || {};
            const toPermissions = ENHANCED_PERMISSION_MATRIX[toRole] || {};
            
            const fromTotal = Object.values(fromPermissions).reduce((sum, levels) => sum + (levels?.length || 0), 0);
            const toTotal = Object.values(toPermissions).reduce((sum, levels) => sum + (levels?.length || 0), 0);
            const increase = toTotal - fromTotal;
            
            const fromDisplay = roleAccounts[fromRole]?.displayName || fromRole;
            const toDisplay = roleAccounts[toRole]?.displayName || toRole;
            
            if (increase > 0) {
                addLog(`📈 权限升级：${fromDisplay}(${fromTotal}个权限) → ${toDisplay}(${toTotal}个权限) [+${increase}]`, 'success');
            }
            
            // 分析新增的权限范围
            const newScopes = [];
            Object.keys(toPermissions).forEach(scope => {
                const fromLevels = fromPermissions[scope] || [];
                const toLevels = toPermissions[scope] || [];
                
                if (fromLevels.length === 0 && toLevels.length > 0) {
                    const scopeTitle = {
                        'SCHOOL_WIDE': '全校范围',
                        'DEPARTMENT': '部门范围', 
                        'CLASS': '班级范围',
                        'GRADE': '年级范围'
                    }[scope];
                    newScopes.push(`${scopeTitle}(${toLevels.length}级)`);
                }
            });
            
            if (newScopes.length > 0) {
                addLog(`🆕 新增权限范围：${newScopes.join('、')}`, 'info');
            }
        }
        
        // 更新升级总结
        function updateUpgradeSummary() {
            const summaryElement = document.getElementById('upgradeSummary');
            if (!summaryElement) return;
            
            const currentStep = Math.min(upgradeDemo.currentStep, ROLE_UPGRADE_PATH.length - 1);
            const currentRole = ROLE_UPGRADE_PATH[currentStep];
            const permissions = ENHANCED_PERMISSION_MATRIX[currentRole.roleCode] || {};
            const totalPermissions = Object.values(permissions).reduce((sum, levels) => sum + (levels?.length || 0), 0);
            const scopeCount = Object.keys(permissions).filter(scope => permissions[scope]?.length > 0).length;
            
            summaryElement.innerHTML = `
                <div style="font-size: 1.1rem; margin-bottom: 10px;">
                    🎯 当前演示角色：<strong>${currentRole.displayName}</strong>
                </div>
                <div style="font-size: 0.9rem; color: rgba(255, 255, 255, 0.8);">
                    权限统计：${totalPermissions}个权限级别 | ${scopeCount}个权限范围 | 
                    升级进度：${upgradeDemo.currentStep}/${ROLE_UPGRADE_PATH.length}
                </div>
            `;
        }
        
        // 完成升级演示
        function finishUpgradeDemo() {
            upgradeDemo.isRunning = false;
            
            // 生成完整权限升级报告
            generateUpgradeReport();
            
            addLog('🎉 权限升级路径演示完成！', 'success');
            addLog('📊 完整的权限升级分析报告已生成', 'info');
            
            // 重置所有步骤状态
            setTimeout(() => {
                document.querySelectorAll('.path-step').forEach(step => {
                    step.classList.remove('active');
                });
            }, 3000);
        }
        
        // 生成升级报告
        function generateUpgradeReport() {
            const animationArea = document.getElementById('permissionAnimationArea');
            if (!animationArea) return;
            
            let reportHTML = `
                <div class="upgrade-report">
                    <h4>📊 权限升级完整分析报告</h4>
                    <div class="report-sections">
            `;
            
            // 各角色权限统计
            reportHTML += `
                <div class="report-section">
                    <h5>🎯 各角色权限统计对比</h5>
                    <div class="role-comparison-grid">
            `;
            
            ROLE_UPGRADE_PATH.forEach((role, index) => {
                const permissions = ENHANCED_PERMISSION_MATRIX[role.roleCode] || {};
                const totalPermissions = Object.values(permissions).reduce((sum, levels) => sum + (levels?.length || 0), 0);
                const scopeCount = Object.keys(permissions).filter(scope => permissions[scope]?.length > 0).length;
                
                reportHTML += `
                    <div class="role-stat-card">
                        <div class="role-icon" style="background: ${role.color}">${role.icon}</div>
                        <div class="role-name">${role.displayName}</div>
                        <div class="role-stats">
                            <div class="stat">权限级别：${totalPermissions}</div>
                            <div class="stat">权限范围：${scopeCount}</div>
                        </div>
                    </div>
                `;
            });
            
            reportHTML += `
                    </div>
                </div>
            `;
            
            // 权限增长分析
            reportHTML += `
                <div class="report-section">
                    <h5>📈 权限升级增长分析</h5>
                    <div class="growth-analysis">
            `;
            
            for (let i = 1; i < ROLE_UPGRADE_PATH.length; i++) {
                const fromRole = ROLE_UPGRADE_PATH[i - 1];
                const toRole = ROLE_UPGRADE_PATH[i];
                
                const fromPermissions = ENHANCED_PERMISSION_MATRIX[fromRole.roleCode] || {};
                const toPermissions = ENHANCED_PERMISSION_MATRIX[toRole.roleCode] || {};
                
                const fromTotal = Object.values(fromPermissions).reduce((sum, levels) => sum + (levels?.length || 0), 0);
                const toTotal = Object.values(toPermissions).reduce((sum, levels) => sum + (levels?.length || 0), 0);
                const growth = toTotal - fromTotal;
                const growthPercent = fromTotal > 0 ? ((growth / fromTotal) * 100).toFixed(1) : 'N/A';
                
                reportHTML += `
                    <div class="growth-item">
                        <div class="growth-path">
                            ${fromRole.displayName} → ${toRole.displayName}
                        </div>
                        <div class="growth-stats">
                            权限增加：${growth} (+${growthPercent}%)
                        </div>
                    </div>
                `;
            }
            
            reportHTML += `
                    </div>
                </div>
            `;
            
            reportHTML += `
                    </div>
                </div>
            `;
            
            animationArea.innerHTML = reportHTML;
            animationArea.style.display = 'block';
            
            // 添加报告样式
            addUpgradeReportStyles();
        }
        
        // 添加升级报告样式
        function addUpgradeReportStyles() {
            const styleId = 'upgrade-report-styles';
            if (document.getElementById(styleId)) return;
            
            const style = document.createElement('style');
            style.id = styleId;
            style.textContent = `
                .upgrade-report {
                    background: rgba(255, 255, 255, 0.1);
                    border-radius: 15px;
                    padding: 25px;
                    margin-top: 20px;
                    backdrop-filter: blur(10px);
                    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
                }
                
                .upgrade-report h4 {
                    color: #fff;
                    text-align: center;
                    margin-bottom: 25px;
                    text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
                }
                
                .report-sections {
                    display: flex;
                    flex-direction: column;
                    gap: 25px;
                }
                
                .report-section {
                    background: rgba(255, 255, 255, 0.05);
                    border-radius: 12px;
                    padding: 20px;
                }
                
                .report-section h5 {
                    color: #ffc107;
                    margin-bottom: 15px;
                    text-align: center;
                }
                
                .role-comparison-grid {
                    display: grid;
                    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
                    gap: 15px;
                }
                
                .role-stat-card {
                    background: rgba(255, 255, 255, 0.1);
                    border-radius: 10px;
                    padding: 15px;
                    text-align: center;
                    border: 1px solid rgba(255, 255, 255, 0.2);
                }
                
                .role-icon {
                    width: 40px;
                    height: 40px;
                    border-radius: 50%;
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    font-size: 1.2rem;
                    color: white;
                    margin: 0 auto 10px;
                }
                
                .role-name {
                    color: #fff;
                    font-weight: bold;
                    margin-bottom: 8px;
                }
                
                .role-stats .stat {
                    color: rgba(255, 255, 255, 0.8);
                    font-size: 0.85rem;
                    margin: 2px 0;
                }
                
                .growth-analysis {
                    display: flex;
                    flex-direction: column;
                    gap: 12px;
                }
                
                .growth-item {
                    background: rgba(255, 255, 255, 0.1);
                    border-radius: 8px;
                    padding: 12px;
                    display: flex;
                    justify-content: space-between;
                    align-items: center;
                }
                
                .growth-path {
                    color: #fff;
                    font-weight: 500;
                }
                
                .growth-stats {
                    color: #28a745;
                    font-weight: bold;
                }
            `;
            
            document.head.appendChild(style);
        }
        
        // 显示升级模拟器
        function showUpgradeSimulator() {
            addLog('🧪 启动权限升级模拟器...', 'info');
            
            // 显示所有角色的权限详情对比
            showView('permission-upgrade');
            
            const animationArea = document.getElementById('permissionAnimationArea');
            if (!animationArea) return;
            
            let simulatorHTML = `
                <div class="upgrade-simulator">
                    <h4>🧪 权限升级模拟器</h4>
                    <div class="simulator-description">
                        选择起始角色和目标角色，模拟查看权限升级的具体变化
                    </div>
                    
                    <div class="simulator-controls">
                        <div class="role-selector">
                            <label>起始角色：</label>
                            <select id="fromRoleSelect" onchange="updateSimulation()">
                                ${ROLE_UPGRADE_PATH.map(role => 
                                    `<option value="${role.roleCode}">${role.displayName}</option>`
                                ).join('')}
                            </select>
                        </div>
                        <div class="upgrade-arrow-sim">→</div>
                        <div class="role-selector">
                            <label>目标角色：</label>
                            <select id="toRoleSelect" onchange="updateSimulation()">
                                ${ROLE_UPGRADE_PATH.map(role => 
                                    `<option value="${role.roleCode}">${role.displayName}</option>`
                                ).join('')}
                            </select>
                        </div>
                    </div>
                    
                    <div class="simulation-result" id="simulationResult">
                        <!-- 模拟结果将在这里显示 -->
                    </div>
                </div>
            `;
            
            animationArea.innerHTML = simulatorHTML;
            animationArea.style.display = 'block';
            
            // 设置默认值
            document.getElementById('fromRoleSelect').value = 'STUDENT';
            document.getElementById('toRoleSelect').value = 'PRINCIPAL';
            
            // 添加模拟器样式
            addSimulatorStyles();
            
            // 初始化模拟
            updateSimulation();
        }
        
        // 更新权限升级模拟
        function updateSimulation() {
            const fromRole = document.getElementById('fromRoleSelect').value;
            const toRole = document.getElementById('toRoleSelect').value;
            const resultContainer = document.getElementById('simulationResult');
            
            if (!resultContainer) return;
            
            const fromPermissions = ENHANCED_PERMISSION_MATRIX[fromRole] || {};
            const toPermissions = ENHANCED_PERMISSION_MATRIX[toRole] || {};
            
            const fromDisplay = roleAccounts[fromRole]?.displayName || fromRole;
            const toDisplay = roleAccounts[toRole]?.displayName || toRole;
            
            // 计算权限变化
            const changes = analyzePermissionChanges(fromPermissions, toPermissions);
            
            let resultHTML = `
                <div class="simulation-header">
                    <h5>📊 ${fromDisplay} → ${toDisplay} 权限变化分析</h5>
                </div>
                
                <div class="change-summary">
                    <div class="summary-stats">
                        <div class="stat-card ${changes.totalChange >= 0 ? 'positive' : 'negative'}">
                            <div class="stat-number">${changes.totalChange >= 0 ? '+' : ''}${changes.totalChange}</div>
                            <div class="stat-label">权限级别变化</div>
                        </div>
                        <div class="stat-card ${changes.scopeChange >= 0 ? 'positive' : 'negative'}">
                            <div class="stat-number">${changes.scopeChange >= 0 ? '+' : ''}${changes.scopeChange}</div>
                            <div class="stat-label">权限范围变化</div>
                        </div>
                    </div>
                </div>
                
                <div class="detailed-changes">
                    <h6>📋 详细权限变化列表：</h6>
            `;
            
            // 显示每个范围的变化
            ['SCHOOL_WIDE', 'DEPARTMENT', 'CLASS', 'GRADE'].forEach(scope => {
                const scopeConfig = {
                    'SCHOOL_WIDE': { title: '全校范围', icon: '🏫' },
                    'DEPARTMENT': { title: '部门范围', icon: '🏢' }, 
                    'CLASS': { title: '班级范围', icon: '🎓' },
                    'GRADE': { title: '年级范围', icon: '📚' }
                }[scope];
                
                const fromLevels = fromPermissions[scope] || [];
                const toLevels = toPermissions[scope] || [];
                
                if (fromLevels.length !== toLevels.length || !fromLevels.every(level => toLevels.includes(level))) {
                    const changeType = toLevels.length > fromLevels.length ? 'gain' : 
                                      toLevels.length < fromLevels.length ? 'loss' : 'change';
                    
                    resultHTML += `
                        <div class="change-item ${changeType}">
                            <div class="change-scope">
                                ${scopeConfig.icon} ${scopeConfig.title}
                            </div>
                            <div class="change-detail">
                                从 ${fromLevels.length > 0 ? fromLevels.map(l => `${l}级`).join(',') : '无权限'} 
                                → ${toLevels.length > 0 ? toLevels.map(l => `${l}级`).join(',') : '无权限'}
                            </div>
                        </div>
                    `;
                }
            });
            
            resultHTML += `
                </div>
            `;
            
            resultContainer.innerHTML = resultHTML;
        }
        
        // 分析权限变化
        function analyzePermissionChanges(fromPermissions, toPermissions) {
            const fromTotal = Object.values(fromPermissions).reduce((sum, levels) => sum + (levels?.length || 0), 0);
            const toTotal = Object.values(toPermissions).reduce((sum, levels) => sum + (levels?.length || 0), 0);
            
            const fromScopes = Object.keys(fromPermissions).filter(scope => fromPermissions[scope]?.length > 0).length;
            const toScopes = Object.keys(toPermissions).filter(scope => toPermissions[scope]?.length > 0).length;
            
            return {
                totalChange: toTotal - fromTotal,
                scopeChange: toScopes - fromScopes,
                fromTotal,
                toTotal,
                fromScopes,
                toScopes
            };
        }
        
        // 添加模拟器样式
        function addSimulatorStyles() {
            const styleId = 'simulator-styles';
            if (document.getElementById(styleId)) return;
            
            const style = document.createElement('style');
            style.id = styleId;
            style.textContent = `
                .upgrade-simulator {
                    background: rgba(255, 255, 255, 0.1);
                    border-radius: 15px;
                    padding: 25px;
                    backdrop-filter: blur(10px);
                    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
                }
                
                .upgrade-simulator h4 {
                    color: #fff;
                    text-align: center;
                    margin-bottom: 15px;
                    text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
                }
                
                .simulator-description {
                    color: rgba(255, 255, 255, 0.8);
                    text-align: center;
                    margin-bottom: 25px;
                    font-size: 0.95rem;
                }
                
                .simulator-controls {
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    gap: 20px;
                    margin-bottom: 30px;
                    flex-wrap: wrap;
                }
                
                .role-selector {
                    display: flex;
                    flex-direction: column;
                    align-items: center;
                    gap: 8px;
                }
                
                .role-selector label {
                    color: #ffc107;
                    font-weight: bold;
                    font-size: 0.9rem;
                }
                
                .role-selector select {
                    padding: 8px 15px;
                    border-radius: 8px;
                    border: 2px solid rgba(255, 255, 255, 0.2);
                    background: rgba(255, 255, 255, 0.1);
                    color: #fff;
                    font-size: 0.9rem;
                    backdrop-filter: blur(5px);
                }
                
                .role-selector select:focus {
                    outline: none;
                    border-color: #ffc107;
                }
                
                .upgrade-arrow-sim {
                    font-size: 2rem;
                    color: #ffc107;
                    font-weight: bold;
                }
                
                .simulation-result {
                    margin-top: 20px;
                }
                
                .simulation-header h5 {
                    color: #fff;
                    text-align: center;
                    margin-bottom: 20px;
                    text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3);
                }
                
                .change-summary {
                    margin-bottom: 25px;
                }
                
                .summary-stats {
                    display: flex;
                    justify-content: center;
                    gap: 20px;
                    flex-wrap: wrap;
                }
                
                .stat-card {
                    background: rgba(255, 255, 255, 0.1);
                    border-radius: 10px;
                    padding: 15px;
                    text-align: center;
                    min-width: 120px;
                    border: 2px solid transparent;
                }
                
                .stat-card.positive {
                    border-color: #28a745;
                    background: rgba(40, 167, 69, 0.1);
                }
                
                .stat-card.negative {
                    border-color: #dc3545;
                    background: rgba(220, 53, 69, 0.1);
                }
                
                .stat-number {
                    font-size: 1.5rem;
                    font-weight: bold;
                    color: #fff;
                    margin-bottom: 5px;
                }
                
                .stat-label {
                    color: rgba(255, 255, 255, 0.8);
                    font-size: 0.85rem;
                }
                
                .detailed-changes {
                    background: rgba(0, 0, 0, 0.1);
                    border-radius: 10px;
                    padding: 20px;
                }
                
                .detailed-changes h6 {
                    color: #ffc107;
                    margin-bottom: 15px;
                    text-align: center;
                }
                
                .change-item {
                    display: flex;
                    justify-content: space-between;
                    align-items: center;
                    padding: 12px;
                    margin: 8px 0;
                    border-radius: 8px;
                    border-left: 4px solid;
                }
                
                .change-item.gain {
                    background: rgba(40, 167, 69, 0.1);
                    border-left-color: #28a745;
                }
                
                .change-item.loss {
                    background: rgba(220, 53, 69, 0.1);
                    border-left-color: #dc3545;
                }
                
                .change-item.change {
                    background: rgba(255, 193, 7, 0.1);
                    border-left-color: #ffc107;
                }
                
                .change-scope {
                    color: #fff;
                    font-weight: bold;
                }
                
                .change-detail {
                    color: rgba(255, 255, 255, 0.8);
                    font-size: 0.9rem;
                }
            `;
            
            document.head.appendChild(style);
        }
        
        // 全角色权限对比
        function compareAllRoles() {
            addLog('📊 生成全角色权限对比分析...', 'info');
            
            showView('permission-upgrade');
            
            const animationArea = document.getElementById('permissionAnimationArea');
            if (!animationArea) return;
            
            let comparisonHTML = `
                <div class="all-roles-comparison">
                    <h4>📊 全角色权限完整对比矩阵</h4>
                    <div class="comparison-description">
                        完整展现5个角色在4个权限范围内的级别分布和差异对比
                    </div>
                    
                    <div class="comparison-matrix">
                        <table class="permission-matrix-table">
                            <thead>
                                <tr>
                                    <th class="role-header">角色</th>
                                    <th>🏫 全校范围</th>
                                    <th>🏢 部门范围</th>
                                    <th>🎓 班级范围</th>
                                    <th>📚 年级范围</th>
                                    <th>统计</th>
                                </tr>
                            </thead>
                            <tbody>
            `;
            
            ROLE_UPGRADE_PATH.forEach(role => {
                const permissions = ENHANCED_PERMISSION_MATRIX[role.roleCode] || {};
                const totalPermissions = Object.values(permissions).reduce((sum, levels) => sum + (levels?.length || 0), 0);
                const scopeCount = Object.keys(permissions).filter(scope => permissions[scope]?.length > 0).length;
                
                comparisonHTML += `
                    <tr>
                        <td class="role-cell">
                            <div class="role-info">
                                <span class="role-icon" style="background: ${role.color}">${role.icon}</span>
                                <span class="role-name">${role.displayName}</span>
                            </div>
                        </td>
                `;
                
                ['SCHOOL_WIDE', 'DEPARTMENT', 'CLASS', 'GRADE'].forEach(scope => {
                    const levels = permissions[scope] || [];
                    const cellClass = levels.length > 0 ? 'has-permission' : 'no-permission';
                    
                    comparisonHTML += `
                        <td class="permission-cell ${cellClass}">
                            ${levels.length > 0 ? 
                                `<div class="permission-levels">
                                    ${levels.map(level => `<span class="level-badge">${level}级</span>`).join('')}
                                </div>` : 
                                '<span class="no-perm">无权限</span>'
                            }
                        </td>
                    `;
                });
                
                comparisonHTML += `
                        <td class="stats-cell">
                            <div class="stat-item">级别：${totalPermissions}</div>
                            <div class="stat-item">范围：${scopeCount}</div>
                        </td>
                    </tr>
                `;
            });
            
            comparisonHTML += `
                            </tbody>
                        </table>
                    </div>
                    
                    <div class="comparison-insights">
                        <h5>🔍 权限分布洞察</h5>
                        <div class="insights-grid">
            `;
            
            // 生成洞察分析
            const insights = generatePermissionInsights();
            insights.forEach(insight => {
                comparisonHTML += `
                    <div class="insight-card">
                        <div class="insight-icon">${insight.icon}</div>
                        <div class="insight-content">
                            <div class="insight-title">${insight.title}</div>
                            <div class="insight-description">${insight.description}</div>
                        </div>
                    </div>
                `;
            });
            
            comparisonHTML += `
                        </div>
                    </div>
                </div>
            `;
            
            animationArea.innerHTML = comparisonHTML;
            animationArea.style.display = 'block';
            
            // 添加对比样式
            addComparisonStyles();
        }
        
        // 生成权限洞察
        function generatePermissionInsights() {
            return [
                {
                    icon: '👑',
                    title: '权限巅峰角色',
                    description: '校长拥有所有16个权限级别，实现全范围全级别管控'
                },
                {
                    icon: '⚖️',
                    title: '权限平衡设计',
                    description: '教务主任在全校范围1级通知需要审批，体现权力制衡'
                },
                {
                    icon: '🎯',
                    title: '专业化分工',
                    description: '教师专注部门和班级事务，班主任专注班级和年级管理'
                },
                {
                    icon: '📈',
                    title: '梯度权限增长',
                    description: '从学生1个权限到校长16个权限，形成合理的权限阶梯'
                }
            ];
        }
        
        // 添加对比样式
        function addComparisonStyles() {
            const styleId = 'comparison-styles';
            if (document.getElementById(styleId)) return;
            
            const style = document.createElement('style');
            style.id = styleId;
            style.textContent = `
                .all-roles-comparison {
                    background: rgba(255, 255, 255, 0.1);
                    border-radius: 15px;
                    padding: 25px;
                    backdrop-filter: blur(10px);
                    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
                }
                
                .all-roles-comparison h4 {
                    color: #fff;
                    text-align: center;
                    margin-bottom: 15px;
                    text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
                }
                
                .comparison-description {
                    color: rgba(255, 255, 255, 0.8);
                    text-align: center;
                    margin-bottom: 25px;
                    font-size: 0.95rem;
                }
                
                .comparison-matrix {
                    overflow-x: auto;
                    margin-bottom: 30px;
                }
                
                .permission-matrix-table {
                    width: 100%;
                    border-collapse: collapse;
                    background: rgba(255, 255, 255, 0.05);
                    border-radius: 10px;
                    overflow: hidden;
                }
                
                .permission-matrix-table th {
                    background: rgba(255, 193, 7, 0.2);
                    color: #ffc107;
                    padding: 15px 10px;
                    text-align: center;
                    font-weight: bold;
                    border-bottom: 2px solid rgba(255, 193, 7, 0.3);
                }
                
                .role-header {
                    background: rgba(255, 193, 7, 0.3) !important;
                    width: 120px;
                }
                
                .permission-matrix-table td {
                    padding: 12px 10px;
                    text-align: center;
                    border-bottom: 1px solid rgba(255, 255, 255, 0.1);
                }
                
                .role-cell {
                    background: rgba(255, 255, 255, 0.1) !important;
                    width: 120px;
                }
                
                .role-info {
                    display: flex;
                    align-items: center;
                    gap: 8px;
                }
                
                .role-icon {
                    width: 30px;
                    height: 30px;
                    border-radius: 50%;
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    color: white;
                    font-size: 0.9rem;
                }
                
                .role-name {
                    color: #fff;
                    font-weight: bold;
                    font-size: 0.9rem;
                }
                
                .permission-cell.has-permission {
                    background: rgba(40, 167, 69, 0.1);
                }
                
                .permission-cell.no-permission {
                    background: rgba(108, 117, 125, 0.1);
                }
                
                .permission-levels {
                    display: flex;
                    flex-direction: column;
                    gap: 3px;
                    align-items: center;
                }
                
                .level-badge {
                    background: #28a745;
                    color: white;
                    padding: 2px 6px;
                    border-radius: 10px;
                    font-size: 0.7rem;
                    font-weight: bold;
                }
                
                .no-perm {
                    color: rgba(255, 255, 255, 0.5);
                    font-size: 0.8rem;
                }
                
                .stats-cell {
                    background: rgba(255, 255, 255, 0.05);
                    font-size: 0.8rem;
                }
                
                .stat-item {
                    color: rgba(255, 255, 255, 0.8);
                    margin: 2px 0;
                }
                
                .comparison-insights {
                    margin-top: 30px;
                }
                
                .comparison-insights h5 {
                    color: #ffc107;
                    text-align: center;
                    margin-bottom: 20px;
                }
                
                .insights-grid {
                    display: grid;
                    grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
                    gap: 15px;
                }
                
                .insight-card {
                    background: rgba(255, 255, 255, 0.1);
                    border-radius: 10px;
                    padding: 15px;
                    display: flex;
                    align-items: flex-start;
                    gap: 12px;
                    border: 1px solid rgba(255, 255, 255, 0.1);
                }
                
                .insight-icon {
                    font-size: 1.5rem;
                    flex-shrink: 0;
                }
                
                .insight-content {
                    flex: 1;
                }
                
                .insight-title {
                    color: #fff;
                    font-weight: bold;
                    margin-bottom: 5px;
                    font-size: 0.9rem;
                }
                
                .insight-description {
                    color: rgba(255, 255, 255, 0.8);
                    font-size: 0.8rem;
                    line-height: 1.4;
                }
            `;
            
            document.head.appendChild(style);
        }
        
        // 重置升级演示
        function resetUpgradeDemo() {
            upgradeDemo.isRunning = false;
            upgradeDemo.currentStep = 0;
            
            // 清除动画区域
            const animationArea = document.getElementById('permissionAnimationArea');
            if (animationArea) {
                animationArea.innerHTML = '';
                animationArea.style.display = 'none';
            }
            
            // 重置路径步骤
            document.querySelectorAll('.path-step').forEach(step => {
                step.classList.remove('active');
                const permissionContainer = step.querySelector('.step-permissions');
                if (permissionContainer) {
                    permissionContainer.classList.remove('show');
                    permissionContainer.innerHTML = '';
                }
            });
            
            // 重置升级总结
            const summaryElement = document.getElementById('upgradeSummary');
            if (summaryElement) {
                summaryElement.innerHTML = '点击"🎬 自动演示升级路径"查看详细的权限变化动画';
            }
            
            
            addLog('🔄 权限升级演示已重置', 'info');
        }
        
        // 增强版错误处理演示功能
        
        // 创建演示错误类型
        function createDemoErrors() {
            return [
                {
                    name: '网络连接错误',
                    error: new Error('Failed to fetch: 网络连接已断开'),
                    context: { operation: '获取用户数据', url: 'http://localhost:48081/api/user' }
                },
                {
                    name: '身份认证错误',
                    error: new Error('HTTP 401: Unauthorized - Token已过期'),
                    context: { operation: '用户登录', token: 'expired_token_xxx' }
                },
                {
                    name: '权限不足错误',
                    error: new Error('HTTP 403: Forbidden - 权限不足，无法访问该资源'),
                    context: { operation: '删除通知', requiredRole: 'PRINCIPAL', currentRole: 'STUDENT' }
                },
                {
                    name: '服务器内部错误',
                    error: new Error('HTTP 500: Internal Server Error - 数据库连接失败'),
                    context: { operation: '保存通知', server: 'localhost:48081' }
                },
                {
                    name: '请求超时错误',
                    error: new Error('请求超时 (30秒)'),
                    context: { operation: '上传文件', timeout: 30000 }
                },
                {
                    name: '数据验证错误',
                    error: new Error('validation failed: 邮箱格式不正确'),
                    context: { operation: '用户注册', field: 'email', value: 'invalid-email' }
                }
            ];
        }
        
        // 演示增强版错误处理
        function demonstrateEnhancedErrorHandling() {
            const demoErrors = createDemoErrors();
            let currentIndex = 0;
            
            addLog('🎭 开始增强版错误处理演示', 'info');
            
            function showNextError() {
                if (currentIndex < demoErrors.length) {
                    const demo = demoErrors[currentIndex];
                    addLog(`📋 演示错误类型: ${demo.name}`, 'info');
                    
                    // 创建重试函数
                    const retryFunction = async () => {
                        addLog(`🔄 模拟重试: ${demo.name}`, 'info');
                        return new Promise(resolve => {
                            setTimeout(() => {
                                addLog(`✅ 重试成功: ${demo.name}`, 'success');
                                resolve('重试成功');
                            }, 1000);
                        });
                    };
                    
                    // 显示增强版错误
                    ErrorNotificationSystem.showEnhancedError(demo.error, {
                        ...demo.context,
                        retryFunction: retryFunction,
                        showDetails: true,
                        reportToServer: false
                    });
                    
                    currentIndex++;
                    
                    // 每隔3秒显示下一个错误
                    setTimeout(showNextError, 3000);
                } else {
                    addLog('🎉 错误处理演示完成！', 'success');
                }
            }
            
            showNextError();
        }
        
        // 测试自动重试机制
        async function testAutoRetryMechanism() {
            addLog('🔄 开始自动重试机制测试', 'info');
            
            let attemptCount = 0;
            const maxAttempts = 2;
            
            // 模拟失败的API调用
            const flakyApiCall = async () => {
                attemptCount++;
                addLog(`🔄 API调用尝试 #${attemptCount}`, 'info');
                
                if (attemptCount <= maxAttempts) {
                    throw new Error('网络连接不稳定，请求失败');
                }
                
                addLog('✅ API调用成功！', 'success');
                return { success: true, data: 'API响应数据' };
            };
            
            try {
                const result = await RetryManager.executeWithRetry(
                    flakyApiCall,
                    ErrorTypes.NETWORK,
                    { operation: '测试API调用' }
                );
                
                addLog(`🎉 自动重试测试成功: ${JSON.stringify(result)}`, 'success');
                
            } catch (error) {
                addLog(`❌ 自动重试测试失败: ${error.message}`, 'error');
            }
        }
        
        // 测试错误分析器
        function testErrorAnalyzer() {
            addLog('🔍 开始错误分析器测试', 'info');
            
            const testCases = [
                new Error('Failed to fetch'),
                new Error('HTTP 401: Unauthorized'),
                new Error('HTTP 403: Forbidden'),
                new Error('HTTP 500: Internal Server Error'),
                new Error('请求超时'),
                new Error('validation failed: 格式错误'),
                new Error('未知的系统错误')
            ];
            
            testCases.forEach((error, index) => {
                const errorInfo = ErrorAnalyzer.analyzeError(error, { testCase: index + 1 });
                addLog(`📊 错误分析 #${index + 1}: 类型=${errorInfo.type}, 严重程度=${errorInfo.severity}, 可重试=${errorInfo.canRetry}`, 'info');
                
                // 显示错误信息
                setTimeout(() => {
                    ErrorNotificationSystem.showEnhancedError(error, {
                        testCase: index + 1,
                        showDetails: false,
                        reportToServer: false
                    });
                }, index * 500);
            });
        }
        
        // 在页面末尾添加测试按钮
        document.addEventListener('DOMContentLoaded', function() {
            // 等待页面完全加载后再添加演示按钮
            setTimeout(() => {
                try {
                    const container = document.querySelector('.container');
                    if (container) {
                        const demoSection = document.createElement('div');
                        demoSection.style.cssText = `
                            margin-top: 30px;
                            padding: 20px;
                            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
                            border-radius: 12px;
                            box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
                        `;
                        
                        demoSection.innerHTML = `
                            <div style="color: white; text-align: center; margin-bottom: 20px;">
                                <h3 style="margin: 0 0 10px 0; font-size: 20px;">🚀 Phase 6 Enhancement: 增强版错误处理演示</h3>
                                <p style="margin: 0; opacity: 0.9; font-size: 14px;">体验智能错误分析、自动重试机制和用户友好的错误反馈系统</p>
                            </div>
                            <div style="background: rgba(255, 255, 255, 0.1); padding: 15px; border-radius: 8px; margin-bottom: 20px; color: white; font-size: 13px;">
                                <strong>✅ 已完成的错误处理优化：</strong><br>
                                • <strong>智能错误分析</strong>：自动识别网络、认证、权限、服务器、超时、验证等7种错误类型<br>
                                • <strong>分层错误处理</strong>：根据错误严重程度提供不同的显示时长和恢复策略<br>
                                • <strong>自动重试机制</strong>：网络和服务器错误支持智能重试，最多3次<br>
                                • <strong>用户友好提示</strong>：每个错误都提供具体的解决建议和操作指导<br>
                                • <strong>视觉增强</strong>：渐变色彩、动画效果、响应式设计和详情模态框<br>
                                • <strong>向后兼容</strong>：保持原有 showErrorAlert 接口，自动升级为增强版功能
                            </div>
                            <div style="display: flex; gap: 10px; flex-wrap: wrap; justify-content: center;">
                                <button onclick="demonstrateEnhancedErrorHandling()" style="
                                    background: rgba(255, 255, 255, 0.2);
                                    color: white;
                                    border: 1px solid rgba(255, 255, 255, 0.3);
                                    padding: 10px 20px;
                                    border-radius: 8px;
                                    cursor: pointer;
                                    font-size: 14px;
                                    transition: all 0.3s ease;
                                " onmouseover="this.style.background='rgba(255,255,255,0.3)'" onmouseout="this.style.background='rgba(255,255,255,0.2)'">
                                    🎭 错误类型演示
                                </button>
                                <button onclick="testAutoRetryMechanism()" style="
                                    background: rgba(255, 255, 255, 0.2);
                                    color: white;
                                    border: 1px solid rgba(255, 255, 255, 0.3);
                                    padding: 10px 20px;
                                    border-radius: 8px;
                                    cursor: pointer;
                                    font-size: 14px;
                                    transition: all 0.3s ease;
                                " onmouseover="this.style.background='rgba(255,255,255,0.3)'" onmouseout="this.style.background='rgba(255,255,255,0.2)'">
                                    🔄 自动重试测试
                                </button>
                                <button onclick="testErrorAnalyzer()" style="
                                    background: rgba(255, 255, 255, 0.2);
                                    color: white;
                                    border: 1px solid rgba(255, 255, 255, 0.3);
                                    padding: 10px 20px;
                                    border-radius: 8px;
                                    cursor: pointer;
                                    font-size: 14px;
                                    transition: all 0.3s ease;
                                " onmouseover="this.style.background='rgba(255,255,255,0.3)'" onmouseout="this.style.background='rgba(255,255,255,0.2)'">
                                    🔍 智能分析测试
                                </button>
                                <button onclick="showEnhancedErrorAlert('这是一个增强版错误提示的演示！', {operation: '功能演示', showDetails: true})" style="
                                    background: rgba(40, 167, 69, 0.3);
                                    color: white;
                                    border: 1px solid rgba(40, 167, 69, 0.5);
                                    padding: 10px 20px;
                                    border-radius: 8px;
                                    cursor: pointer;
                                    font-size: 14px;
                                    transition: all 0.3s ease;
                                " onmouseover="this.style.background='rgba(40,167,69,0.4)'" onmouseout="this.style.background='rgba(40,167,69,0.3)'">
                                    ✨ 快速体验
                                </button>
                            </div>
                            <div style="margin-top: 15px; padding: 10px; background: rgba(255, 255, 255, 0.1); border-radius: 8px; color: white; font-size: 13px; text-align: center;">
                                <strong>💡 使用提示:</strong> 点击按钮体验不同类型的错误处理演示。每个错误通知都提供详细建议、重试选项和错误详情查看功能。
                            </div>
                        `;
                        
                        container.appendChild(demoSection);
                        addLog('🎭 增强版错误处理演示区域已加载', 'success');
                    }
                } catch (error) {
                    console.error('创建演示区域失败:', error);
                }
            }, 2000);
        });
    </script>
</body>
</html>